前言
上篇,我们聊到了栈和用栈解一道简单算法题,在这篇文章,我们将运用栈的知识解两道难度偏中的算法题。
题目739.每日温度
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]
提示:
1 <= temperatures.length <= 105
30 <= temperatures[i] <= 100
解题思路
这题可使用暴力解法,每遍历一个温度就将其与之后的温度对比,不过这样的时间复杂度过大,为n^2,当数据过大时不能通过测试,所以这题不能用暴力解法。 故这题我们运用单调栈来解决:
- 定义一个距离数组,用于记录下一个更高温度的距离,大小与温度数组相同,将其填满0;
- 温度从左到右遍历,第一个温度入栈,如果第二个温度更高,则更新对应的距离数组且第一个温度出栈;
- 如果第二个温度更低,则第二个温度入栈,第三个温度同上;
- 直到找到更高温度,再更新对应的距离数组且该温度出栈。
解题代码
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
const len = temperatures.length;
const stack = []
const res = new Array(len).fill(0)
for (let i = 0; i < len; i++) {
while (stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {
const top = stack.pop()
res[top] = i - top
}
stack.push(i)
}
return res
};
题目LCR147.最小栈
请你设计一个 最小栈 。它提供 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],[2],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,2,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(2);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 2.
minStack.getMin(); --> 返回 -2.
提示:
-231 <= val <= 231 - 1
pop
、top
和getMin
操作总是在 非空栈 上调用push
、pop
、top
和getMin
最多被调用3 * 104
次
解题思路
为了实现一个可以在常数时间内检索到最小元素的最小栈(MinStack),我们可以使用两个栈来解决这个问题:一个主栈(用于存储所有元素),另一个辅助栈(用于存储每个位置的最小元素)。这样,当我们需要获取当前栈的最小值时,只需要返回辅助栈的栈顶元素即可。
-
构造函数:初始化两个栈,一个用于存储所有元素(
stack
),另一个用于存储当前的最小元素(minStack
)。 -
push(val) :将元素推入主栈。如果辅助栈为空或当前元素小于等于辅助栈的栈顶元素,则将当前元素推入辅助栈。
-
pop() :弹出主栈的栈顶元素。如果弹出的元素与辅助栈的栈顶元素相等,则将辅助栈的栈顶元素也弹出。
-
top() :返回主栈的栈顶元素。
-
getMin() :返回辅助栈的栈顶元素,这就是当前栈中的最小元素。
解题代码
/**
* initialize your data structure here.
*/
var MinStack = function () {
this.stack = [];
this.min = [];
};
MinStack.prototype.push = function (x) {
if (!this.min.length || x <= this.min[this.min.length - 1]) {
this.min.push(x)
}
this.stack.push(x);
};
MinStack.prototype.pop = function () {
if (this.stack.pop() === this.min[this.min.length - 1]) {
this.min.pop()
}
};
MinStack.prototype.top = function () {
if (!this.stack.length) return
return this.stack[this.stack.length - 1]
};
MinStack.prototype.getMin = function () {
return this.min[this.min.length - 1]
};
/**
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(x)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.getMin()
*/
总结
栈的运用可以帮助我们解决很多难以解决的算法问题,学习好栈对面试和就业也是至关重要的,希望这篇文章对你有所帮助