堆棧基礎node
堆棧(stack)具備「後進先出」的特性,利用這個特性咱們能夠用堆棧來解決這樣一類問題:後續的輸入會影響到前面的階段性結果。線性地遍歷輸入並用stack處理,這類問題較簡單,求解時間複雜度通常爲O(n)。git
相關LeetCode題:github
844. Backspace String Compare 題解spa
1047. Remove All Adjacent Duplicates In String 題解code
735. Asteroid Collision 題解blog
150. Evaluate Reverse Polish Notation 題解遞歸
堆棧處理嵌套關係element
堆棧還能夠用於解決嵌套類問題,例如 LeetCode 856. Score of Parentheses,時間複雜度O(n):
//856. Score of Parentheses int scoreOfParentheses(string S) { stack<int> st; st.push(0); //最終結果 for(char c:S){ if(c=='(') st.push(0); //暫存中間結果 else{ int val=st.top();st.pop(); val=st.top()+max(val*2,1); st.pop(); //更新中間和最終結果 st.push(val); } } return st.top(); }
這類問題的難點在於理解嵌套過程,分析在單個嵌套開始時如何用stack暫存狀態、對應嵌套結束時如何更新狀態。嵌套問題通常也可使用遞歸求解,遞歸解法理解起來比堆棧解法更直觀:直至嵌套的中心、層層往外處理。
相關LeetCode題:
856. Score of Parentheses 堆棧題解 遞歸題解
341. Flatten Nested List Iterator 題解
636. Exclusive Time of Functions 題解
單調棧
形如這樣的問題也可用堆棧解決:對一個數組,對每一個元素求大於或小於該元素的下一個數,例如 LeetCode 503. Next Greater Element II:
//503. Next Greater Element II vector<int> nextGreaterElements(vector<int>& nums) { vector<int> res(nums.size(),-1); stack<int> st; for(int i=nums.size()-1;i>=0;i--) st.push(i); for(int i=nums.size()-1;i>=0;i--){ while(!st.empty()&&nums[i]>=nums[st.top()]) st.pop(); if(!st.empty()) res[i]=nums[st.top()]; st.push(i); } return res; }
以上堆棧形式叫單調棧(monotone stack),棧內元素單調遞增或遞減,用其能夠實現O(n)時間複雜度求解問題。
相關LeetCode題:
503. Next Greater Element II 題解
1063. Number of Valid Subarrays 題解