一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 3 天,点击查看活动详情。
每日温度
给定一个整数数组 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 <=30 <= temperatures[i] <= 100
思路分析
方法一
- 看到题目的第一思路就是遍历数组找出离当前项最近的那个比它大的数字,将间距存储下来;
- 定义结果数组,遍历数组,定义需要找的下标
j = i + 1,以j < len为终止条件循环,若temperatures[j] > temperatures[i],则将res[i]赋值为j - i,同时跳出当前循环;否则,res[i] = 0; - 最后返回结果数组
res。最终耗时3220ms,所以还可以优化。
方法二
- 此方法使用单调栈的方法;
- 定义一个栈,倒序遍历数组,如果当前值大于栈中的顶值,则将最后一项出栈;在遍历完成后,每个温度会对应一个栈,那么有更高温度时,需要计算是在几天后,
res[i] = stack.length ? stack[stack.length - 1][1] - i : 0,若没有则为0; - 此方法大大的缩减了运行时间。
AC 代码
方法一
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
const res = []
const len = temperatures.length
for(let i = 0; i < len; i++) {
let j = i + 1
while(j < len) {
if(temperatures[j] > temperatures[i]) {
res[i] = j - i
break
} else {
res[i] = 0
}
j++
}
}
return res
};
结果:
- 执行结果: 通过
- 执行用时:3220 ms, 在所有 JavaScript 提交中击败了5.04%的用户
- 内存消耗:61.5 MB, 在所有 JavaScript 提交中击败了61.95%的用户
- 通过测试用例:47 / 47
方法二
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
// 单调栈
const res = []
const stack = []
for (let i = temperatures.length - 1; i >= 0; i--) {
const current = temperatures[i]
while (stack.length && current >= stack[stack.length - 1][0]) {
stack.pop()
}
// 有更高的温度直接计算是几天后
res[i] = stack.length ? stack[stack.length - 1][1] - i : 0
stack.push([current, i])
}
return res;
};
结果:
- 执行结果: 通过
- 执行用时:200 ms, 在所有 JavaScript 提交中击败了78.71%的用户
- 内存消耗:64.7 MB, 在所有 JavaScript 提交中击败了5.23%的用户
- 通过测试用例:47 / 47