数据结构与算法---(最小栈)

文章介绍了如何实现一个最小栈,包括暴力版本、辅助栈实现和最优的存差值方法。每种方法都详细说明了其实现逻辑,以及相应的时间和空间复杂度分析。
摘要由CSDN通过智能技术生成

最小栈

题目需求:

实现一个这样的栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值。栈里面存放的都是 int 整数,
力扣题目:实现一个最小栈

暴力版本实现

时间复杂度为O(n);空间复杂度为O(1)
采用一个指针来指向最小元素下标,每次出栈都要判断出栈元素是否是当前最小,如果是就要去遍历,更新最小指针,

class MinStack {
    int[] nums;
    int minIndex;
    int index;

    /** initialize your data structure here. */
    public MinStack() {
        this.nums=new int[20000];
        this.index=0;
        this.minIndex=-1;
    }    
    public void push(int x) {
        nums[index]=x;
        index++;
        if(minIndex==-1){
            minIndex=0;
        }else if(x<nums[minIndex]){
            minIndex=index-1;
        }
    }
    
    public void pop() {
        index--;
        if(index==minIndex){
            minIndex=0;
            for(int i=0;i<index;i++){
                if(nums[i]<=nums[minIndex]){
                    minIndex=i;
                }
            }
        }
        
    }
    
    public int top() {
        return nums[index-1];
    }
    
    public int min() {
        return nums[minIndex];
    }
}
辅助栈实现

采用一个辅助栈来实现,其时间复杂度为O(1),空间复杂度为O(n)
有两个栈 s1和 s2,s1 是目标栈,s2 是辅助栈,用来存放最小值。

  1. 每次 getMin 的时候,直接从 s2 栈顶获取即可
  2. 每次入栈,s1直接入栈,s2则需要判断,若当前入栈元素小于s2的栈顶元素,则直接入栈,若当前元素大于等于s2的栈顶元素,则把s2的栈顶元素值,入栈一次。
  3. 每次出栈,s1,s2都直接弹出即可
  4. 需要注意,若首次入栈,也可以当s2为空栈的时候,直接将当前元素入栈
class MinStack {
    Stack<Integer> s1;
    Stack<Integer> s2;
    /** initialize your data structure here. */
    public MinStack() {
        this.s1=new Stack<Integer>();
        this.s2=new Stack<Integer>();
    }    
    public void push(int x) {
        s1.push(x);
        if(s2.empty()){
            s2.push(x);
        }else{
            if(x<s2.peek()){
            s2.push(x);
            }else{
                s2.push(s2.peek());
            }
        }
    }
    
    public void pop() {
        s1.pop();
        s2.pop();
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int min() {
        return s2.peek();
    }
}
使用存差值实现(最优)
public class MinStack {

    private Stack<Integer> stack = new Stack<Integer>();
    private int min;

    public void push(int x) {
        if (stack.isEmpty()) {
            min = x;
            stack.push(0);
        } else {
            // 计算差值
            int compare = x - min;
            stack.push(compare);
            // 如果差值小于0,显然 x 成为最小值,否则最小值不变
            min = compare < 0 ? x : min;
        }
    }

    public void pop() {
        int top = stack.peek();
        // 如果top小于0,显然最小值也一并会被删除,此时更新最小值
		
        min = top < 0 ? (min - top) : min;
        stack.pop();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值