力扣【下一个更大元素】leetcode-503.下一个更大元素 Ⅱ:单调栈解法+循环数组解法
題目:
思路與解法:
1、如果是暴力法,只需要遍歷就可以了,但是那樣的話時間復雜度就是O(N^2);
2、可以把這幾個數字,抽象成為高度不一樣的柱子;
3、尋找的過程,就是從當前柱子去看,被后面的哪一個柱子首先擋住
4、使用單調棧,每一次有新元素加入的時候,進行處理,保持棧內的元素是單調的;這樣的很巧妙;棧是先進后出的,而且是找“第一個大的”,就是棧中最小的;所以,使用一個單調減的單調棧
5、由于使用棧,棧是先進后出的;從后面開始遍歷,倒過來入棧,最后棧出來的順序才是和原數組的順序是一樣的;
6、單調棧中存的是什么?
動態的看,是:(從當前位置)從前往后,第一個看見的柱子,第二個看見的柱子,第三個看見的柱子····如此;因為兩個高個子柱子中間的那一個柱子,從前面肯定是看不到的;
7、循環數組的巧妙處理:做好for()循環的條件控制,i = 2*n - 1; 看起來就是遍歷了兩次數組一樣;做好正確讀取對應的值(取余%) nums[i%n];這樣就沒必要去雙倍擴充數組了!
由此得到如下框架:
for(從后往前遍歷) { 循環數組處理:i = 2*n - 1; nums[i%n]while () {新元素進來,排序一次;被擋住看不見的就出棧}判斷 {如果棧空,沒更大的了,輸出 -1;否則;輸出棧頂元素} 新元素來,進棧 }代碼:
class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {int n = nums.size();vector<int> res(n);stack<int> s; //單調棧解法 和 739題每日溫度相似;多了循環數組的處理//不去增倍數組,使用循環數組;//循環數組,只是 索引 i 變大了,所以for 循環里面效果似乎是兩次//處理的時候,nums[i%n] 就是讀取到真的數字for (int i = 2 * n - 1; i >= 0; i --) {while (!s.empty() && s.top()<= nums[i%n] ) {s.pop();//反正擋住了,就出棧,保持單調}res[i%n] = s.empty() ? -1 : s.top();s.push(nums[i%n]);//進新的 以便后一步判斷}return res;} };結果:
總結:
1、感覺最重要的,首先就是有這樣一個抽象的思維,好比建模一樣,把每一個數字,抽象成“高低不同的柱子”,然后想象成在前面投影,后面的第一個可以看見的柱子,就是需要找的那一個。
2、隨后是對于 “棧” 的理解;棧是先進去后出來的,所以從后遍歷;其中還要做好對棧進行處理,保持是一個單調的棧
3、循環數組的巧妙處理,一是只需要做好for()循環的條件控制,二是正確讀取對應的值(取余%);這樣節約了空間,還起了一樣的效果;
總結
以上是生活随笔為你收集整理的力扣【下一个更大元素】leetcode-503.下一个更大元素 Ⅱ:单调栈解法+循环数组解法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 力扣【接雨水问题】 leetcode-4
- 下一篇: linux下gdb使用core文件调试程