leetcode456 132模式

给定一个整数序列:a1, a2, …, an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj。设计一个算法,当给定有 n 个数字的序列时,验证这个序列中是否含有132模式的子序列。

注意:n 的值小于15000。

示例1:

输入: [1, 2, 3, 4]

输出: False

解释: 序列中不存在132模式的子序列。
示例 2:

输入: [3, 1, 4, 2]

输出: True

解释: 序列中有 1 个132模式的子序列: [1, 4, 2].
示例 3:

输入: [-1, 3, 2, 0]

输出: True

解释: 序列中有 3 个132模式的的子序列: [-1, 3, 2], [-1, 3, 0] 和 [-1, 2, 0].

题解:

如果直接暴力,那么就会达到O(n3)的时间复杂度,实际上这个题连时间复杂度O(n2)都过不了。

本题的解法是维护一个从左向右的最小数组,和一个从右向左的递减栈。

如下所示:

在这里插入图片描述

到这里,看到栈顶元素大于min,并且小于当前元素0.说明已经找到了满足132的模式串。可以返回了。

这里最小栈的栈顶一定只能保存比当前元素小并且比当前min大的数。所以每次要根据min对战进行弹出。保证栈顶是大于min的。而且如果此时栈顶元素小于当前元素说明找到了,不然将当前元素放入栈顶,继续下一个找。这样维护的栈是一个递减栈。

时间复杂度O(n)

空间复杂度O(n)

java代码:

    public boolean find132pattern(int[] nums) {
        if(nums.length<3)return false;
        int[] left = new int[nums.length];
        Stack<Integer> right  =new Stack<>();
        left[0] = nums[0];
        for(int i = 0;i<nums.length;i++){
            left[i] = Math.min(nums[i],left[i-1]);
        }
        for(int i = nums.length-1;i>=0;i--){
            if(right.isEmpty()){
                right.push(nums[i]);
                continue;
            }
            while(right.peek()<=left[i]){
                right.pop();
            }
            if(right.isEmpty()){
                right.push(nums[i]);
                continue;
            }

            if(right.peek()<nums[i])
                return true;
            else
                right.push(nums[i]);
        }
        return false;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值