456132 模式(单调栈)

1、题目描述

给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。

如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。

提示:

n == nums.length
1 <= n <= 2 * 105
-109 <= nums[i] <= 109

2、示例

输入:nums = [3,1,4,2]
输出:true
解释:序列中有 1 个 132 模式的子序列: [1, 4, 2] 。

3、题解

基本思想:单调栈,我们从后往前做,维护一个「单调递减」的栈,如果当前元素大于栈顶元素,栈顶元素出栈,更新k为最大的出栈元素,最后当前元素push入栈,这样就得到满足条件的j k,栈内元素就是j,出栈的最大元素就是k,因为k是出栈元素j是入栈元素所以序号j<k,又因为当前元素大于栈顶元素即栈内元素大于出栈元素所以值j>k,这个时候如果当前元素nums[i]<k&&栈非空,就得到满足条件的i j k,其中因为k初始化为INT_MIN,如果nums[i]<k说明k是出栈得到的,栈内必有元素。

k 记录所有出栈元素的最大值(k 代表满足 132 结构中的 2)。那么当我们遍历到 i,只要满足发现满足 nums[i] < k,说明我们找到了符合条件的 i j k。
举例,对于样例数据 [3, 1, 4, 2],我们知道满足 132 结构的子序列是 [1, 4, 2],其处理逻辑是(遍历从后往前):
枚举到 2:栈内元素为 [2],k = INF
枚举到 4:不满足「单调递减」,2 出栈更新 k,4 入栈。栈内元素为 [4],k = 2
枚举到 1:满足 nums[i] < k,说明对于 i 而言,后面有一个比其大的元素(满足 i < k 的条件),同时这个 k 的来源又是因为维护「单调递减」而弹出导致被更新的(满足 i 和 k 之间,有比 k 要大的元素)。因此我们找到了满足 132 结构的组合。
这样做的本质是:我们通过维护「单调递减」来确保已经找到了有效的 (j,k)。换句话说如果 k 有值的话,那么必然是因为有 j > k,导致的有值。也就是 132 结构中,我们找到了 32,剩下的 i (也就是 132 结构中的 1)则是通过遍历过程中与 k 的比较来找到。这样做的复杂度是 O(n)的。

class Solution {
public:
    bool find132pattern(vector<int>& nums) {
        if(nums.size()<3)
            return false;
        int k=INT_MIN;
        stack<int> st;
        for(int i=nums.size()-1;i>=0;i--)
        {
            if(nums[i]<k)
                return true;
            while(!st.empty()&&st.top()<nums[i])
            {
                k=max(st.top(),k);
                st.pop();
            }
            st.push(nums[i]);
        }
        return false;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值