演算法與資料結構基礎 - 堆疊(Stack)
堆疊基礎
堆疊(stack)具有“後進先出”的特性,利用這個特性我們可以用堆疊來解決這樣一類問題:後續的輸入會影響到前面的階段性結果。線性地遍歷輸入並用stack處理,這類問題較簡單,求解時間複雜度一般為O(n)。
相關LeetCode題:
13. Roman to Integer 題解
20. Valid Parentheses 題解
844. Backspace String Compare 題解
1047. Remove All Adjacent Duplicates In String 題解
735. Asteroid Collision 題解
150. Evaluate Reverse Polish Notation 題解
堆疊處理巢狀關係
堆疊還可以用於解決巢狀類問題,例如 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 堆疊題解 遞迴題解
394. Decode String 堆疊題解 遞迴題解
341. Flatten Nested List Iterator 題解
385. Mini Parser 題解
636. Exclusive Time of Functions 題解
224. Basic Calculator 題解
772. Basic Calculator III 題解
單調棧
形如這樣的問題也可用堆疊解決:對一個數組,對每個元素求大於或小於該元素的下一個數,例如 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 題解
739. Daily Temperatures 題解
901. Online Stock Span 題解
1063. Number of Valid Subarrays 題解
1019. Next Greater Node In Linked List 題解
84. Largest Rectangle in Histogram 題解
&n