1. 程式人生 > >演算法與資料結構基礎 - 堆疊(Stack)

演算法與資料結構基礎 - 堆疊(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