前端刷题路-Day82:最小栈(题号155)

·  阅读 103
前端刷题路-Day82:最小栈(题号155)

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

最小栈(题号155)

题目

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

  • 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.
复制代码

提示:

  • poptopgetMin 操作总是在 非空栈 上调用。

链接

leetcode-cn.com/problems/mi…

解释

这题啊,这题是简我击失败了。

面试中被问到了,结果没答出来啊~

如果正常刷题的话是没问题啊,结果面试时不知道是不是因为太紧张,一点思路都没有,最后还是在面试官的提醒下答出来的。

当时怎么想都是O(n)的时间复杂度啊,O(1)是真的想不出来。

O(n)其实很好操作,直接用Math.min直接取最小值即可,这没啥可说的。

O(1)的话就得考虑到最小元素的获取时机了。

先将这个问题拆解下,如果想在getMin时变成O(1),那么证明获取最小数字的位置应该在push或者pop,那总不能在pushpop时都执行下Math.min吧,这样虽然让getMin强行O(1)了,但是其本质上没有变化,还是O(n)的时间复杂度。

其实这题的根源就在于push操作,要做的也很简单,在每次push的情况下记录当前的最小数字,下一次push的时候拿当前的值来和上一次push的最小值进行比较,然后记录当前位置的最小值即可。

pop操作单纯取出数组的最后一个元素即可,别的没有任何的多余操作了,需要做的只是维护一个变量,这个变量可以是数组,也可以是对象,每次只需要取出上一个长度的最小值,然后更新当前长度的最小值。

想明白之后真的非常简单,可惜当时没想出来,唉~

自己的答案

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];
};
复制代码

整体思路就是这样,在MinStack内部需要再维持一个数组用来记录当前位置的最小值,push的时候往min_stack中推入一个新元素,这个元素是min_stack的最后一个元素和当前插入值的最小值;pop的时候需要去掉x_stack的最后一个元素和min_stack的最后一个元素,籍此来保持min_stack的最后一个元素一直都是最新最小值;top直接取x_stack的最后一个元素;getMinmin_stack的最后一个元素即可。

典型的用空间换时间,没想出来真是可惜了

更好的方法



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

分类:
前端