运用栈解算法题——单调栈、最小栈(下)

39 阅读3分钟

前言

上篇,我们聊到了栈和用栈解一道简单算法题,在这篇文章,我们将运用栈的知识解两道难度偏中的算法题。

题目739.每日温度

leetcode.cn/problems/da…

给定一个整数数组 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.最小栈

leetcode.cn/problems/ba…

请你设计一个 最小栈 。它提供 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
  • poptop 和 getMin 操作总是在 非空栈 上调用
  • pushpoptop 和 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()
 */

总结

栈的运用可以帮助我们解决很多难以解决的算法问题,学习好栈对面试和就业也是至关重要的,希望这篇文章对你有所帮助