携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
题目描述
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
解题思路——暴力双重循环
面试的时候实在不会也要写出暴力法,至少不会失分。
对于长度为 n 的 temperatures 数组来说,第 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();
};
解题思路——单调栈
暴力解法固然爽,但是如果你用个别语言去提交代码的话,说不定就超时了,懂我意思吧。
所以我们需要想个办法,能减少遍历次数或者循环次数,要不然有10000个温度,最高的都在后面,那不是gg了。
所以新招式就是“单调栈”。单调栈首先得是栈,然后才是单调性质,可以是单调增,也可以是单调减。这时候有小伙伴跳出来问了,“凭什么突然蹦个单调栈解法啊,我怎么知道要用单调栈了?”
我先给出定论:当你需要在左区间或右区间,查找一个比当前的数大或者小的数时,就可以考虑使用单调栈了。
在这题里体现的就是往右区间找一个比当前数大的值,所以使用单调栈。
这里我用数组模拟栈,每个元素都是一个数组,形式为 [第i天的温度temperatures[i],第i天]。
步骤如下:
- 初始化一个单调栈
stack,一个length=temperatures.length的结果数组ans并填充为0。 - 遍历
temperatures数组,查找栈,如果栈为空则将[temperatures[i], i]作为一个元素push入栈,继续遍历。 - 查找栈,栈不为空时,我们比较栈顶元素
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;
};