【LeetCode-栈】最小栈

题目描述

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。
  • pop() —— 删除栈顶的元素。
  • top() —— 获取栈顶元素。
  • getMin() —— 检索栈中的最小元素。

示例:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

说明:
pop、top 和 getMin 操作总是在 非空栈 上调用。
题目链接: https://leetcode-cn.com/problems/min-stack/

思路1

这个题的难点在于用常数时间获取最小值,其他的操作都可以使用常规的栈实现。为了在常数时间内获得最小值,我们除了存储数据的栈 dataStack 外,还需要一个辅助栈 helperStack,helperStack 存储 将数据压入到 dataStack 的过程中遇到的最小元素。算法步骤如下:
将 x 入栈:

  • 将 x 压入 dataStack,如果 helperStack 为空或者 x <= helperStack.top(),那么将 x 压入 helperStack;

出栈:

  • 如果 dataStack 的栈顶元素等于 helperStack 的栈顶元素,则两个栈均出栈;
  • 否则,只将 dataStack 的栈顶元素出栈;

获取最小值:

  • 返回 helperStack 的栈顶元素即可。

例如,我们将 [-2, 0, -3] 依次压入到栈中:

  • 压入 -2: dataStack = [-2], helperStack = [-2];
  • 压入 0:dataStack = [-2, 0],因为 0 大于 helperStack 的栈顶元素 -2,所以不将 0 压入 helperStack,helperStack 依旧是 [-2]
  • 压入 -3:dataStack = [-2, 0, -3], 因为 -3 小于等于 helperStack 的栈顶元素 -2,所以将 -3 压入到 helperStack,此时 helperStack = [-2, -3]

模拟获取最小值以及出栈过程:

  • 获取最小值:helperStack.top() == -3,就是最小值;
  • 出栈:此时 dataStack 为 [-2, 0],因为出栈元素 -3 等于 helperStack 的栈顶元素,所以将 helperStack 的栈顶元素 -3 也出栈;
  • 获取最小值:helperStack.top() == -2,就是最小值。

代码如下:

class MinStack {
    stack<int> dataStack, helpStack;
public:
    /** initialize your data structure here. */
    MinStack() {
        
    }
    
    void push(int x) {
        dataStack.push(x);
        if(helpStack.empty() || x<=helpStack.top()){  // 注意是 <=,不是 <
            helpStack.push(x);
        }
    }
    
    void pop() {
        if(dataStack.top()==helpStack.top()){
            dataStack.pop();
            helpStack.pop();
        }else{
            dataStack.pop();
        }
    }
    
    int top() {
        return dataStack.top();
    }
    
    int getMin() {
        return helpStack.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();
 */

思路2

使用一个栈,栈同时存放当前元素和当前的最小元素,可以使用pair来包装起来,栈的定义为stack<pair<int, int>> s,pair 的第一个元素是当前入栈元素,pair 的第二个元素是当前的最小值。入栈的时候需要进行判断,假设入栈元素为 x,入栈时:

  • 如果 s 为空,则 s.push(make_pair(x, x));
  • 否则,将 x 和 s.top().second(当前栈的最小元素)比较:
    • 如果 x <= s.top().second,则 s.push(make_pair(x, x));
    • 否则,s.push(make_pair(x, s.top().second));

这样入栈的话,s.top().second 就是当前的最小元素。
代码如下:

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

/**
 * 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();
 */
posted @ 2020-05-12 22:01  Flix  阅读(179)  评论(0编辑  收藏  举报