LC 最小栈

题目描述

设计一个支持 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 操作总是在 非空栈 上调用

标签:

栈   设计

思路

一开始想用一个值存储最小值,但是若这个值被弹出不就没了嘛……
那建一个结构体,放值和位置,若是最小值就将结构体放到数组minLst中,删除时若是最小值,且是这个位置,则就移动minLst的游标
(下面是初始代码,有点啰嗦……还能再简洁点……)

#include<bits/stdc++.h>
using namespace std;
class MinStack {
public:
    /** initialize your data structure here. */
    struct Node{
        int val;
        int pos;
    };
    int min;
    int data[10000];
    Node* minLst[1000];
    int pre;
    int last;
    

    MinStack() {
        min=INT_MAX;
        pre=-1;
        last=-1;
    }
    
    void push(int val) {
        if(val < min)
        {
            min=val;
            Node *n=(Node*)malloc(sizeof(Node));
            n->val=val;
            n->pos=(pre+1);
            minLst[++last]=n;
        }
        data[++pre]=val;
    }
    
    void pop() {
        if(pre==-1)
            return ;
        if(last>0 && data[pre]==min && minLst[last]->pos==pre)
            min=minLst[--last]->val;
        pre--;
    }
    
    int top() {
        if(pre==-1)
            return NULL;
        return data[pre];
    }
    
    int getMin() {
        return min;
    }
};

/**
 * 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();
 */

问题:若一直pop,pop到minLst结束后会越界……

然后再官方题解发现了辅助栈这种东西……

辅助栈

  1. 定义“数据栈”:支持push、pop、top操作
  2. 定义“辅助栈”:栈顶为当前最小值,以支持常数时间复杂度的getMin
    (若是最小值,则同时压入辅助栈;若pop出时最小值,辅助栈也要出栈)

在将数据入栈时,将此数据此时对应的最小值也入辅助栈
此时状态是辅助栈的元素和数据栈的元素相等,辅助与数据栈进出平行

class MinStack {
    stack<int> x_stack;
    stack<int> min_stack;
public:
    /** initialize your data structure here. */
    MinStack() {
        min_stack.push(INT_MAX);
    }
    
    void push(int val) {
        x_stack.push(val);
        min_stack.push(min(min_stack.top(),val));
    }
    
    void pop() {
        x_stack.pop();
        min_stack.pop();
    }
    
    int top() {
        return x_stack.top();
    }
    
    int getMin() {
        return min_stack.top();
    }
};

/**
 * 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();
 */

同类python代码:

class MinStack:
    def __init__(self):
        self.stack=[]
        self.min_stack = [math.inf]

    def push(self,x:int)->None:
        self.stack.append(x)
        self.min_stack.append(min(x,self.min_stack[-1]))

    def pop(self)->None:
        self.stack.pop()
        self.min_stack.pop()

    def top(self)->int:
        return self.stack[-1]

    def getMin(self)->int:
        return self.min_stack[-1]

保存对应最小值

不用辅助栈,则可用其他思路达到此效果:

  1. 用结点保存当前对应最小值
  2. 用pair打包成一组
class MinStack{
    private:
        stack<pair<int,int>> st;
    public:
    /** initialize your data structure here. */
    MinStack() {
    }
    void push(int x)
    {
        if(st.size()==0)
            st.push({x,x});
        else
            st.push({x,min(x,st.top().second)});
    }

    void pop()
    {
        st.pop();
    }
        
    int top()
    {
        return st.top().first;
    }

    int getMin()
    {
        return st.top().second;
    }
};

python版:

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        if not self.stack:
            self.stack.append((x, x))
        else:
            self.stack.append((x, min(x, self.stack[-1][1])))
        

    def pop(self):
        """
        :rtype: void
        """
        self.stack.pop()
        

    def top(self):
        """
        :rtype: int
        """
        return self.stack[-1][0]
        

    def getMin(self):
        """
        :rtype: int
        """
        return self.stack[-1][1]


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

自定义Stack

以单链表形式自定义栈:

private static class Node{
	int val;
	int min;
	Node next;

	public Node(int val,int min){
		this(val,min,null);
	}
	
	public Node(int val,int min,Node next){
		this.val=val;
		this.min=min;
		this.next=next;
	}

不用额外结构

参考这里(下面改为C++版)
min要更新时,先将之前存储的min入栈,再将新值入栈
当要取出这个min时,再pop出一个就是上一轮的min

入栈 2 ,同时将之前的 min 值 3 入栈,再把 2 入栈,同时更新 min = 2
| 2 |   min = 2
| 3 |  
| 5 |     
|_3_|    
stack  

入栈 6 
| 6 |  min = 2
| 2 |   
| 3 |  
| 5 |     
|_3_|    
stack  

出栈 6     
| 2 |   min = 2
| 3 |  
| 5 |     
|_3_|    
stack  

出栈 2     
| 2 |   min = 2
| 3 |  
| 5 |     
|_3_|    
stack  

出栈 2     
|   |  min = 3   
| 5 |   
|_3_|    
stack  

这样就只需要一个栈,当有更小值来时将之前的最小值入栈,当前更小的值再入栈即可

class MinStack{
    int min=INT_MAX;
    stack<int> s;
    public:
    /** initialize your data structure here. */
    MinStack() {
    }
    void push(int x)
    {
        if(x<=min)
        {
            s.push(min);
            min=x;
        }
        s.push(x);
    }

    void pop()
    {
        if(s.top()==min)
        {
            s.pop();
            min=s.top();
        }
        s.pop();
    }
    
    int top()
    {
        return s.top();
    }

    int getMin()
    {
        return min;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值