劍指Offer -20 - 包含min函數的棧 - C++/Java

需要更好的閱讀的體驗請移步 👉 小牛肉的個人博客 👈


題目描述

定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。
注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。

算法思想

該題難點在於最小元素min函數的寫法,使用雙棧法

使用一個棧按照大小順序存儲每次當前所有元素的最小值

比如:
stack1是普通的棧,完成正常操作。用stack2順序存儲最小值元素

  • 初始狀態
    stack1 :
    stack2:

  • 壓入8:stack2爲空,則直接壓入
    stack1 : 8
    stack2: 8

  • 壓入 6:6 小於 stack2 的當前棧頂元素 8,則直接壓入
    stack1 : 8 6
    stack2: 8 6

  • 壓入 5:5 小於 stack2 的當前棧頂元素 6,則直接壓入
    stack1 : 8 6 5
    stack2: 8 6 5

  • 壓入 9:9 大於 stack2 的當前棧頂元素 5,不壓入stack2
    stack1 : 8 6 5 9
    stack2: 8 6 5

  • 壓入 4:4 小於 stack2 的當前棧頂元素 5,則直接壓入
    stack1 : 8 6 5 9 4
    stack2: 8 6 5 4

可以看到,當前棧頂的最小元素就是stack2的棧頂元素 4

  • 出棧1次:stack2的棧頂元素4(當前所有元素的最小值)和stack1的棧頂元素 4 相同,則一併彈出,表示最小元素被更新了
    stack1 : 8 6 5 9
    stack2: 8 6 5

    則當前棧中的最小值變爲5

  • 出棧2次:stack2的棧頂元素5(當前所有元素的最小值)和 stack1的棧頂元素不同,則只需彈出stack1的棧頂即可,說明當前所有元素的最小值不會因爲9的彈出而改變,還是stack2的棧頂元素5
    stack1 : 8 6 5
    stack2: 8 6 5

    則當前棧中的最小值還是5

具體代碼

  • C++
class Solution {
public:
    //stack2用來有序排列stack1中的值,保證值從小到大排列(棧尾-》棧頂)
    // 保證stack2中的棧頂始終是當前棧的最小值
    stack<int> stack1, stack2; 
    void push(int value) {
        stack1.push(value);
        if(stack2.empty()) //如果順序棧爲空,則直接壓入
            stack2.push(value);
        else if(value <= stack2.top()) //如果要壓入的值小於當前順序棧的棧頂,則壓入
            stack2.push(value);
    }
    void pop() {
        // 如果要彈出的值和順序棧的棧頂元素相同,則一併彈出
        // 表示原先棧中的最小值隨着本次彈出操作,原先的最小值被彈出來了
        // 彈出原先的最小值後,當前順序棧stack2的棧頂仍然是當前棧的最小值
        if(stack1.top() == stack2.top())
            stack2.pop();
        stack1.pop();
    }
    int top() {
        return stack1.top();
    }
    int min() {
        return stack2.top();
    }
};
  • Java
import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
        if(stack2.empty())
            stack2.push(node);
        else if(node <= stack2.peek())
            stack2.push(node);
    }
    
    public void pop() {
        if(stack1.peek() == stack2.peek())
            stack2.pop();
        stack1.pop();
    }
    
    public int top() {
        return stack1.peek();
    }
    
    public int min() {
        return stack2.peek();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章