leetcode 456. 132 Pattern(132模式)

Given an array of n integers nums, a 132 pattern is a subsequence of three integers nums[i], nums[j] and nums[k] such that i < j < k and nums[i] < nums[k] < nums[j].

Return true if there is a 132 pattern in nums, otherwise, return false.

Example 1:

Input: nums = [1,2,3,4]
Output: false
Explanation: There is no 132 pattern in the sequence.

Example 2:

Input: nums = [3,1,4,2]
Output: true
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].

判断数组中是否存在132模式,也就是存在i < j < k, 使nums[i] < nums[k] < nums[j]
也就是i, j, k下标,简称为第1,2,3个数,第1个数要比第3个数小,第3个数又比第2个数小。

思路:
要找到第2个数最大,同时第3个数 < 第2个数,但又比第1个数大。
所以理清这样的关系,
为了找到第3个数比第1个数大,最好找到大小仅次于第2个数的数字。

问题就转换为要得到仅仅小于目前得到的最大值的数。

用一个单调栈来解决,因为要找第3个数,所以从后往前遍历数组。
栈里比nums[i]小的全部取出,把nums[i]保存进去,
这样做就是只保留当前最大的元素,所以从栈中取出的最后一个元素就是之前最大的,也就是仅小于当前nums[i]的第3个数,nums[i]就是第2个数。
把第3个数字保存到last变量。

下一次遇到nums[i] < last,就说明找到了第1个数,它满足 < 第3个数的条件,而第3个数 < 第2个数的条件在保存进栈时就已经满足了。

    public boolean find132pattern(int[] nums) {
        int n = nums.length;
        if(n < 3) return false;
        
        Stack<Integer> st = new Stack<>();
        int last = Integer.MIN_VALUE;
        
        for(int i = n - 1; i >= 0; i--) {
            if(nums[i] < last) return true;
            
            while(!st.isEmpty() && nums[i] > st.peek()) last = st.pop();
            
            st.push(nums[i]);
        }
        return false;
    }

用当前数组nums和一个栈顶指针top来模拟栈,效率更高。

    public boolean find132pattern(int[] nums) {
        int n = nums.length;
        if(n < 3) return false;
        int top = n;
        
        int last = Integer.MIN_VALUE;
        
        for(int i = n - 1; i >= 0; i--) {
            if(nums[i] < last) return true;
            
            while(top < n && nums[i] > nums[top]) last = nums[top ++];
            
            nums[--top] = nums[i];
        }
        return false;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值