剑指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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章