【LeetCode热题100】155. 最小栈(栈)

文章介绍了如何在Java中实现一个支持push、pop、top和getMin操作的MinStack类,要求在常数时间内获取最小元素。提供了两种方法:一种是使用辅助栈,另一种是差分法,通过维护栈的最小值来达到高效查询。
摘要由CSDN通过智能技术生成

一.题目要求

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

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

二.题目难度

中等

三.输入样例

示例 1:
输入:
[“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.

提示:
-231 <= val <= 231 - 1
pop、top 和 getMin 操作总是在 非空栈 上调用
push, pop, top, and getMin最多被调用 3 * 104

四.解题思路

逃课了,没用 o ( 1 ) o(1) o(1)的getMin也AC了。贴一下学的不逃课的两个解法吧
解法1:辅助栈,每次入栈的时候将当前val和辅助栈栈顶(也就是栈的最小值进行比较)若比最小值大,则辅助栈压入当前最小值,若比当前最小值还小,则压入val。当val出栈时,辅助栈对应元素也出栈。
解法2:存差值,只需要 o ( 1 ) o(1) o(1)的辅助空间,很巧妙,解释见代码注释。

五.代码实现

解1

class MinStack {
public:
    MinStack() {
        minStk.push(INT_MAX);
    }
    
    void push(int val) {
        if(val < minStk.top())
        {
            minStk.push(val);
            stk.push(val);
        }
        else
        {
            minStk.push(minStk.top());
            stk.push(val);
        }
        
    }
    
    void pop() {
        minStk.pop();
        stk.pop();
    }
    
    int top() {
        return stk.top();
    }
    
    int getMin() {
        return minStk.top();
    }

private:
    stack<int> stk;
    stack<int> minStk;
    //int min = INT_MAX;
};

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

解2 差值法

class MinStack {
public:
    MinStack() {

    }
    //每次存值的时候 存当前值和栈最小值的插值
    void push(int val) {
        if(stk.empty())
        {
        //空栈让当前值为最小值
            nowMin = val;
            stk.push(0);
        }
        else
        {
        	//存当前值和最小值的差值
            stk.push(val - nowMin);
            //若差值大于0,则证明该元素为栈顶元素时,此元素不是最小值
            //若差值小于0,则证明该元素比当前栈最小值还小,更新最小值为当前值
            nowMin = stk.top() < 0 ? val : nowMin;
        }
    }
    
    void pop() {

        long d = stk.top();
		stk.pop();
        //当弹出栈顶元素时,进行判断
        //	1>若当前栈顶差值大于0,则当前弹出的元素不是最小值,不会对最小值造成影响
        //  2>若当前栈顶差值小于0,则以当前元素作为栈顶的栈中,这个值为最小值。
        //(因为差值小于0,表示这个元素的值比这个元素插入之前的栈最小值要小,类似递归的思想)
        // 所以当前元素弹出后,栈恢复成这个元素插入前的栈,最小值恢复成 当前最小值(也就是弹出的这个元素的本身值) — 弹出的差值
        nowMin = d <= 0 ? nowMin - d : nowMin;

    }
    
    int top() {
    	//获取栈顶元素同样需要讨论
    	// 1>若当前栈顶差值大于0,则栈顶实际值为差值+最小值
    	// 2>若小于0,则实际值就是现在的最小值
        if(stk.top() > 0)
        return stk.top() + nowMin;
        else return nowMin;
    }
    
    int getMin() {
        return nowMin;
    }

private:
    stack<long> stk;
    long nowMin;
};

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

六.题目总结

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值