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

目录

题目

解题思路

题解


题目

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

示例:

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/problems/bao-han-minhan-shu-de-zhan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

提示:

  1. 各函数的调用总次数不超过 20000 次

解题思路

分析一下题目,很中规中矩的一道题,push入栈和pop出栈的操作和普通栈的操作一样,唯一需要注意的是min返回当前栈帧中最小值的操作,因为需要其时间复杂度为常数阶,这也就限制了不能使用查找算法来返回最小值而只能以直接返回最小值的方式进行。

此时便需要一个数组,模拟栈帧、一个数组,存放所有栈帧情况下的最小值,方便回溯、一个指针,指向当前栈帧顶部的有效元素。

  1. stack,int类型数组,最大长度为20000。
  2. MinArray,int类型数组,最大长度为20000。
  3. top,int类型变量,初始值为-1。

既然无法使用查找算法查找当前栈帧的最小值,那么便只能每次入栈都将当前栈帧中的最小值保存下来,而且还不能仅使用一个变量来保存最小值,因为每进行一次入栈/出栈操作,当前栈帧的最小值都会改变,因此最小值的存放必须具有回溯功能。因此就可以定义一个数组,与栈帧共用一个指针,在栈帧改变时同步改变数组。

由于存放的是每次入栈/出栈后栈帧的最小值,那么当第一个元素入栈时,栈帧中的最小值就是当前入栈的元素;之后的每一个元素入栈时,由于数组每次存放的是当时栈帧的最小值,那么便只需要将当前入栈的元素值与前一时刻栈帧的最小值进行比较,便可以确定当前栈帧的最小值。

由于栈帧和数组是同步改变的,因此指针指向的位置就是当前栈帧中顶部的有效元素以及当前栈帧中的最小值。


题解

class MinStack {

    int[] stack = new int[20000];   //定义栈
    int[] MinArray = new int[20000];    //存放每次的最小值,方便回溯
    int top;
    /** initialize your data structure here. */
    public MinStack() {
        top = -1;   //永远指向当前栈帧的位置(有效元素位置)
    }
    
    public void push(int x) {
        stack[++top] = x;   //元素入栈
        
        //存放当前栈帧中的最小值
        if(top == 0){   //如果栈帧中只有一个元素,那么最小值就是这个元素
            MinArray[top] = x;
        }else{  //如果栈帧中的元素多余一个,那么只需要和之前栈帧的最小值比较就行
            MinArray[top] = x < MinArray[top - 1] ? x : MinArray[top - 1];
        }
    }
    
    public void pop() {
        --top;
    }
    
    public int top() {
        return stack[top];
    }
    
    public int min() {
        return MinArray[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.min();
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值