剑指 Offer 30. 包含min函数的栈

1. 题目

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

2. 示例

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

3. 题解

本题主要是要看懂要做什么?

是让我们实现一个函数来做栈的相关操作。

两种实现方式:

  • 双栈:
    • 其中一个保持默认栈的方式,另外一个作为非严格降序辅助栈(并不包含所有元素)。
    • push:A栈始终入栈,B栈判断是否为空或者即将入栈元素是否小于栈顶元素,若是,直接入栈。此时,对于大于栈顶的元素未入B栈,但没有影响,因为只需返回最小元素。
    • pop:弹出A栈栈顶元素,判断弹出元素是否与B栈顶想等,若是,B栈也弹出。
    • top:直接返回A栈栈顶元素。
    • min:返回B栈栈顶元素。
  • 单栈
    • 分析上面双栈方式,发现双栈中的辅助站只是为了存储历次的最小值min,但实际在使用过程中,我们只需要维护当前的最小值以及上一次的最小值即可,因而我们可以之际使用单栈来实现。
    • 当前的最小元素为min,上一次的最小元素存入单栈中。

4. 实现

4.1 双栈

 1 class MinStack {
 2 
 3    //维护一个栈,只需要维护当前最小值以及上一次最小值即可
 4    Stack<Integer> stack;
 5    int min;
 6    /** initialize your data structure here. */
 7    public MinStack30() {
 8        stack = new Stack<>();
 9    }
10    public void push(int x) {
11        if(stack.isEmpty()) {
12            min = x;
13        }
14        if(x <= min) {
15            // 记录上一个最小值
16            stack.push(min);
17            min = x;
18        }
19        stack.push(x);
20    }
21    public void pop() {
22        if(min == stack.pop()) {
23            // 还原上一个最小值
24            min = stack.pop();
25        }
26    }
27    public int top() {
28        return stack.peek();
29    }
30    public int min() {
31        return min;
32    }
33 }
View Code

4.2 单栈

 1 public class MinStack {
 2     // 维护一个栈,只需要维护当前最小值以及上一次最小值即可
 3     Stack<Integer> stack;
 4     int min;
 5     /** initialize your data structure here. */
 6     public MinStack() {
 7         stack = new Stack<>();
 8     }
 9     public void push(int x) {
10         if(stack.isEmpty()) {
11             min = x;
12         }
13         // 此处很巧妙,将min入栈,保证min之下都比这个元素小
14         if(x <= min) {
15             // 记录上一个最小值
16             stack.push(min);
17             min = x;
18         }
19         stack.push(x);
20     }
21     public void pop() {
22         if(min == stack.pop()) {
23             // 还原上一个最小值,  stack.push(min)将最小元素存储在了stack里
24             min = stack.pop();
25         }
26     }
27     public int top() {
28         return stack.peek();
29     }
30     public int min() {
31         return min;
32     }
33 }
View Code

5. 结语

  努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!

  如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。

 

posted @ 2021-07-12 20:12  抚琴尘世客  阅读(55)  评论(0编辑  收藏  举报