手摸手提桶跑路——LeetCode155.最小栈

170 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

题目描述

设计一个支持 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.

解题思路

什么是栈

栈是一个后入先出(LIFO)的结构。就相当于一个单出口停车场,先进去的车辆被后进去的车辆堵住了,最先进去的车只能最后一个走,并且是等待后一个进来的车辆走了才能走。

怎么使用数组去模拟栈

一般来说,我们可以使用数组去模拟栈,栈的入栈操作,就相当于向数组的尾部插入元素,对应的就是数组的 push 操作;而栈的出栈操作,弹出的是栈的顶部元素,就相当于数组的 pop 操作;同时,栈的顶就相当于数组的最后一个元素,栈的底就是数组的第一个元素。

思路

原本我是打算使用一个数组去做这道题的,但是每次去调用 getMin 去找最小值的时候,都需要比较栈中的所有元素,查找最小值,时间复杂度是 O(n),而题目要求我们能在常数的时间复杂度里找到最小值。

那么什么是常数时间呢,简单来说,就是你的 查找效率不应该随着数据的变大而变大

微信图片_20201123151920.png

那么我们能不能多用一个成员变量 minValue,每次 push 都和这个 minValue 比较,如果新入栈的值比它小就更新 minValue

微信图片_20220824182841.jpg

原本我也是这么想的,但是后来发现,如果我出栈的时候,把最小值给弹出去了,那么我的 minValue 是不是就不准确了?

说了这么多,那么到底怎么样的数据结构,能满足题目的要求呢。

重置珍藏版思路

我们可以使用另一个数组来模拟栈,来记录每次入栈后,栈的最小值,这个栈也叫 辅助栈

具体步骤如下:

  1. 初始化一个栈 stack, 一个辅助栈 minStack,都为空数组。
  2. 新元素 value 入栈的时候,stack 正常 push,同时比较 value 和 minStack 最后一个元素的大小,表示到当前 stack 的长度为止,栈中的最小值是谁。
  3. 出栈的时候,stack 和 minStack 都要出栈。看起来没什么差别,我们仔细看看:如果 stack 栈顶是最小值,那么 minStack 的栈顶元素也是最小值,它出栈之后,那么 stack 和 minStack 都要出栈,此时 minStack 的栈顶元素又是新的最小值了,刚刚的出栈没有影响。

题解

var MinStack = function() {
    this.x_stack = [];
    this.min_stack = [Infinity];
};

MinStack.prototype.push = function(x) {
    this.x_stack.push(x);
    this.min_stack.push(Math.min(this.min_stack[this.min_stack.length - 1], x));
};

MinStack.prototype.pop = function() {
    this.x_stack.pop();
    this.min_stack.pop();
};

MinStack.prototype.top = function() {
    return this.x_stack[this.x_stack.length - 1];
};

MinStack.prototype.getMin = function() {
    return this.min_stack[this.min_stack.length - 1];
};

微信截图_20220824183915.png