手摸手提桶跑路——LeetCode739. 每日温度

181 阅读1分钟

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

题目描述

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

解题思路——暴力双重循环

面试的时候实在不会也要写出暴力法,至少不会失分。

对于长度为 ntemperatures 数组来说,第 i 天的温度 temperatures[i] 来说,我们要去 temperatures[i + 2]、temperatures[i + 2] ... temperatures[n-1] 中去找下一个更高的温度,那么直接内层再套一个循环,从当前 i 的下一天,也就是 i + 1 开始遍历,直到找到下一个更高的温度为止。

题解

/**
 * @param {number[]} temperatures
 * @return {number[]}
 */
var dailyTemperatures = function(temperatures) {
    const lens = temperatures.length, ans = [];
    for(let i=lens-1; i>=0; --i) {
        let v = 0;
        for(let j=i+1; j<lens; ++j) {
            if(temperatures[i] < temperatures[j]) {
                v = j - i;
                break;
            }
        }
        ans.push(v);
    }
    return ans.reverse();
};

微信截图_20220819163906.png

解题思路——单调栈

暴力解法固然爽,但是如果你用个别语言去提交代码的话,说不定就超时了,懂我意思吧。

QQ图片20220810180329.jpg

所以我们需要想个办法,能减少遍历次数或者循环次数,要不然有10000个温度,最高的都在后面,那不是gg了。

所以新招式就是“单调栈”。单调栈首先得是栈,然后才是单调性质,可以是单调增,也可以是单调减。这时候有小伙伴跳出来问了,“凭什么突然蹦个单调栈解法啊,我怎么知道要用单调栈了?”

微信图片_20220819152846.jpg

我先给出定论:当你需要在左区间或右区间,查找一个比当前的数大或者小的数时,就可以考虑使用单调栈了。

在这题里体现的就是往右区间找一个比当前数大的值,所以使用单调栈。

这里我用数组模拟栈,每个元素都是一个数组,形式为 [第i天的温度temperatures[i],第i天]

步骤如下:

  1. 初始化一个单调栈 stack,一个 length=temperatures.length 的结果数组 ans 并填充为 0
  2. 遍历 temperatures 数组,查找栈,如果栈为空则将 [temperatures[i], i] 作为一个元素 push 入栈,继续遍历。
  3. 查找栈,栈不为空时,我们比较栈顶元素 stackLast 和当天温度 temperatures[i]temperatures[i]>stackLast[0] 这个条件是否成立,成立则说明 stackLast[1] 这天后的第一个更高温找到了,就是第 i 天 温度 temperatures[i],把 i - stackLast[1] 存入 ans[stackLast[1]] 中,就是 stackLast[1] 这天的下一个最高温出现在后面的第几天,然后出栈。由于栈不止一个元素,有可能当天还是前面某天的下一个最高温,所以这边需要循环重复执行步骤3,直到 temperatures[i]>stackLast[0] 这个条件不成立为止。

题解

/**
 * @param {number[]} temperatures
 * @return {number[]}
 */
var dailyTemperatures = function(temperatures) {
    const lens = temperatures.length, ans = new Array(lens).fill(0);
    const stack = [];

    for(let i=0; i<lens; ++i) {
        while(stack.length) {
            const last = stack[stack.length-1];
            if(temperatures[i] > last[0]) {
                ans[last[1]] = i - last[1];
                stack.pop();
            } else {
                break;
            }
        }
        stack.push([temperatures[i], i]);
    }
    return ans;
};

微信截图_20220820151403.png