1. 程式人生 > >[Leetcode]下一個更大元素II

[Leetcode]下一個更大元素II

下一個 實現 ext 操作 暴力 數字 leet 它的 eat

題目

給定一個循環數組(最後一個元素的下一個元素是數組的第一個元素),輸出每個元素的下一個更大元素。數字 x 的下一個更大的元素是按數組遍歷順序,這個數字之後的第一個比它更大的數,這意味著你應該循環地搜索它的下一個更大的數。如果不存在,則輸出 -1。

示例 1:
輸入: [1,2,1]
輸出: [2,-1,2]

解釋: 
第一個 1 的下一個更大的數是 2;
數字 2 找不到下一個更大的數; 
第二個 1 的下一個最大的數需要循環搜索,結果也是 2。
註意: 輸入數組的長度不會超過 10000。

思路:

這道題最簡單的思路就是暴力算法了,效率為O(n^2),可以模擬得出。

最開始我一直以為這道題是動態規劃題,解了好久,但發現不存在最優子結構這個特性,於是換了一種思路-棧。

建立一個存儲下標位置(index)的棧s,我們從nums順序取出元素,判斷這個元素是不是某位數的下一位更大元素。這個判斷操作是通過比較取出的這個元素和棧頂元素,細節如下。

  1. 如果取出的元素更大,說明這個元素是棧頂元素的下一個更大元素,將其放在對應的位置並彈出棧頂值,繼續與下一個比較(所以要用while進行而不是if)

  2. 如果取出的元素更小或者棧已經為空(無法比較了),說明這個元素不是下一個更大元素或者沒有可以比較的元素,則將這個下標壓入棧。

其中代碼還將循環操作進行了一個優化,由於尋找遍歷的元素個數絕對在2n個以內,所以遍歷的時候就將2n作為上限。

代碼的具體實現:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        unsigned len=nums.size();
        vector<int>res(len,-1);
        stack<int>s;
        for(unsigned i=0;i<len*2;i++){
            int num=nums[i%len];
            while(!s.empty()&&nums[s.top()]<num){
                res[s.top()]=num;
                s.pop();
            }
            if(i<len)s.push(i);
            }
        return res;    
    }
        
};

[Leetcode]下一個更大元素II