456. 132 Pattern

本文探讨了在数组中寻找132模式的有效算法,包括枚举法、基于区间的搜索以及利用栈进行优化的方法。通过实例代码展示了每种算法的具体实现过程。

解法

解法一:枚举

最简单粗暴的枚举是需要枚举i,j,k,但是有没有方法可以减少一维呢?
答案是可以的,i只要比j小就可以了,为了方便我们只要选小于j里使得nums[i]最小的那个就行了

class Solution(object):
    def find132pattern(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        n = len(nums)
        if n<=2:
            return False
        minval = nums[0]
        for j in xrange(1,n-1):
            if nums[j]>minval:
                for k in xrange(j+1,n):
                    if nums[k]<nums[j] and nums[k]>minval:
                        return True
            else:
                minval = nums[j]
        return False
        

解法二:基于区间

遍历到每个元素k的时候,就在可能的(i,j)对里搜索,看k是不是在它们之间
为了减少(i,j)对的数量,i不变的时候j要取最大的
假设i固定了,我们遇到第一个s,比i小,那么现在最小值变成s,最大值j也要重新开始算,前一个区间就不再更新了。

要注意,看新遍历的元素在不在已有区间里的时候,也要考虑当前还在更新的那个区间

class Solution(object):
    def find132pattern(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        n = len(nums)
        if n<=2:
            return False
        minval = nums[0]
        maxval = None
        i = 1
        intervals = set()
        while i<n:
            if nums[i]<minval:
                if maxval != None:
                    intervals.add((minval, maxval))
                minval = nums[i]
                maxval = None
            if (maxval == None and nums[i]>minval) or maxval<nums[i]:
                maxval = nums[i]
            if maxval!=None and nums[i]>minval and nums[i]<maxval:
                return True
            for a,b in intervals:
                if nums[i]<b and nums[i]>a:
                    return True
            i += 1    
        return False
        

解法三:栈

对于每个j,它的i最好是它前面的那个最小值
所以我们可以得到一个前缀最小值数组,注意这个数组一定是递减的!!!!!!!
这是栈能用上的重要条件
我们现在从后面往前遍历,找k
假如我们遍历到j,栈顶的元素肯定在j后面

  • 如果它比j对应的那个i小,那么我们可以pop出来,因为它一定没有用了,后面遍历的j对应的i只可能比现在的更大
  • 假如栈顶元素比i大,那么又分两种情况:
    1. 栈顶元素比j小,这显然满足132条件,可以返回了
    2. 栈顶元素不小于j,那么我们把这个元素入栈,于是显然栈的元素也是有序的
class Solution(object):
    def find132pattern(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        n = len(nums)
        if n<=2:
            return False
        minval = nums[0]
        min = [None]*n
        for i in xrange(1,n-1):
            min[i] = minval
            if nums[i]<minval:
                minval = nums[i]
        stack = [nums[-1]]
        for i in xrange(n-2, 0,-1):
            while len(stack) and stack[-1]<=min[i]:
                stack.pop()
            if len(stack)==0 or stack[-1]>nums[i]:
                stack.append(nums[i])
            elif len(stack) and stack[-1]<nums[i]:
                return True
        return False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值