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