LeetCode刷題(二十)-----棧(Java、C++)

155. 最小棧

設計一個支持 push,pop,top 操作,並能在常數時間內檢索到最小元素的棧。
push(x) -- 將元素 x 推入棧中。
pop() -- 刪除棧頂的元素。
top() -- 獲取棧頂元素。
getMin() -- 檢索棧中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

思路一:
解法1:用兩個棧實現最小棧功能
一個棧s存放數據,另一個棧min存放前棧中最小的數據

class MinStack {
public:
    stack<int> s;//數據棧
    stack<int> min;//輔助棧
    /** initialize your data structure here. */
    MinStack() {
        
    }
    
    void push(int x) {
        s.push(x);
        if(min.empty()||x<=min.top())
        {
            min.push(x);
        }
    }
    
    void pop() {
        if(s.top()==min.top())
            min.pop();
        s.pop();
    }
    
    int top() {
        return s.top();
    }
    int getMin() {
        return min.top();
    }
};

解法2:一個棧實現
棧中兩個數據位合成一個單元,第一個數據位存放當前數據到末尾的最小值,第二個數據位存放當前數據

class MinStack {
public:
    /** initialize your data structure here. */
    stack<int> s;
    MinStack() {
        
    }
    
    void push(int x) {
        if(s.empty())
        {
            s.push(x);
            s.push(x);
        }
        else
        {
            int temp=s.top();
            s.push(x);
            if(x<temp)
            {
                s.push(x);
            }
            else
            {
                s.push(temp);
            }
        }
    }
    
    void pop() {
        s.pop();
        s.pop();
    }
    
    int top() {
        int temp=s.top();
        s.pop();
        int top=s.top();
        s.push(temp);
        return top;
    }
    
    int getMin() {
        return s.top();
    }
};

作者:chenlele
鏈接:https://leetcode-cn.com/problems/min-stack/solution/zui-xiao-zhan-by-gpe3dbjds1/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

我的:

class MinStack {
public:
    stack<int> s;//數據棧
    stack<int> min;//輔助棧
    /** initialize your data structure here. */
    MinStack() {
        
    }
    
    void push(int x) 
    {
        s.push(x);
        if(min.empty()||x <= min.top())
        {
            min.push(x);
        }
    }
    
    void pop() 
    {
        if(s.top() == min.top())
        {
            min.pop();
        }      
        s.pop();
    }
    
    int top() {
        return s.top();  
    }
    
    int getMin() {
        return min.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

94. 二叉樹的中序遍歷

給定一個二叉樹,返回它的中序遍歷。
示例:

在這裏插入圖片描述
進階:遞歸算法很簡單,你可以通過迭代算法完成嗎?
思路一:二叉樹的中序遍歷 - 迭代法
解題思路:
• 前序遍歷迭代算法
• 後序遍歷迭代算法
o 第一種方法
o 第二種方法
• 中序遍歷迭代算法
前序遍歷迭代算法:
二叉樹的前序遍歷
二叉樹的遍歷,整體上看都是好理解的。
三種遍歷的迭代寫法中,數前序遍歷最容易理解。
遞歸思路:先樹根,然後左子樹,然後右子樹。每棵子樹遞歸。
在迭代算法中,思路演變成,每到一個節點 A,就應該立即訪問它。
因爲,每棵子樹都先訪問其根節點。對節點的左右子樹來說,也一定是先訪問根。
在 A 的兩棵子樹中,遍歷完左子樹後,再遍歷右子樹。
因此,在訪問完根節點後,遍歷左子樹前,要將右子樹壓入棧。
思路:
在這裏插入圖片描述
代碼:
在這裏插入圖片描述
後序遍歷迭代算法:
二叉樹的後序遍歷
有兩種方法。第一種比第二種要容易理解,但多了個結果逆序的過程。
第一種方法:
我們可以用與前序遍歷相似的方法完成後序遍歷。
後序遍歷與前序遍歷相對稱。
思路: 每到一個節點 A,就應該立即訪問它。 然後將左子樹壓入棧,再次遍歷右子樹。
遍歷完整棵樹後,結果序列逆序即可。
思路:
在這裏插入圖片描述
代碼:
在這裏插入圖片描述
第二種方法:
按照左子樹-根-右子樹的方式,將其轉換成迭代方式。
思路:每到一個節點 A,因爲根要最後訪問,將其入棧。然後遍歷左子樹,遍歷右子樹,最後返回到 A。

但是出現一個問題,無法區分是從左子樹返回,還是從右子樹返回。
因此,給 A 節點附加一個標記T。在訪問其右子樹前,T 置爲 True。之後子樹返回時,當 T 爲 True表示從右子樹返回,否則從左子樹返回。
當 T 爲 false 時,表示 A 的左子樹遍歷完,還要訪問右子樹。

同時,當 T 爲 True 時,表示 A 的兩棵子樹都遍歷過了,要訪問 A 了。並且在 A 訪問完後,A 這棵子樹都訪問完成了。
思路:
在這裏插入圖片描述
代碼:
在這裏插入圖片描述
中序遍歷迭代算法:
二叉樹的中序遍歷
思路:每到一個節點 A,因爲根的訪問在中間,將 A 入棧。然後遍歷左子樹,接着訪問 A,最後遍歷右子樹。
在訪問完 A 後,A 就可以出棧了。因爲 A 和其左子樹都已經訪問完成。
思路:
在這裏插入圖片描述
代碼:
在這裏插入圖片描述
作者:jason-2
鏈接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/die-dai-fa-by-jason-2/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
我的:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> S;
        vector<int> v;
        TreeNode* rt = root;
        while(rt || S.size()){
            while(rt){
                S.push(rt);
                rt=rt->left;
            }
            rt=S.top();S.pop();
            v.push_back(rt->val);
            rt=rt->right;
        }
        return v;  
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章