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;
    }
};

 

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