leetcode456

题目:

给定一个整数序列: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].

 题解:

         这道题的关键是从后往前遍历,为什么呢?因为题目转换为我们要找到1,而1最可能就是在最前面出现的,作为座标最小值也最小的数,因此更大的数3和2就从后面开始遍历。因为3和2的值越大越好。因此使用了递减栈,递减栈的作用是栈顶就是我们现在找到的最大的3,栈中的其他数虽然是大于3的,但是 不可能作为3,因为它们更可能是作为

[2  3  4]

这样的递减数组被加进来的,它们没有符合座标比它们大,值又比它们小的2,因此就被压栈了。但是遍历时一旦发现有值比栈顶大,说明3值可以得到更新,更重要的是,它打破了递减数列,说明2是真实存在的,这也是2初始值为INT_MIN的原因。2当然也是越大越好,因此它就取值为被替换的3的旧值,刚好保证是次小于3的。

代码:

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章