编码母题 / P1 / 经典算法 / 13
每日温度与单调栈
重要程度必练难度中等预计完成20–30 分钟
题目是什么
输入按日期顺序排列的温度数组 temperatures;返回等长数组,第 i 项表示从第 i 天起还要等几天才会遇到第一个严格更高温度,没有则为 0;相同温度不计,空数组返回 []。
输入输出示例
temperatures=[70,70,71] 返回 [2,1,0]:前两天分别等 2 天、1 天,最后一天没有更高温度。
练习起手式与验证
/*
* 题目:每日温度与单调栈
* 要求:输入按日期顺序排列的温度数组 temperatures;返回等长数组,第 i 项表示从第 i 天起还要等几天才会遇到第一个严格更高温度,没有则为 0;相同温度不计,空数组返回 []。
* 示例:temperatures=[70,70,71] 返回 [2,1,0]:前两天分别等 2 天、1 天,最后一天没有更高温度。
*/
function dailyTemperatures(temperatures) {}
console.log(dailyTemperatures([73, 74, 75, 71, 69, 72, 76, 73])); // 预期:[1, 1, 4, 2, 1, 1, 0, 0]
console.log(dailyTemperatures([70, 70, 71])); // 预期:[2, 1, 0]
console.log(dailyTemperatures([3, 2, 1])); // 预期:[0, 0, 0]
console.log(dailyTemperatures([])); // 预期:[]
/*
* 题目:每日温度与单调栈
* 要求:输入按日期顺序排列的温度数组 temperatures;返回等长数组,第 i 项表示从第 i 天起还要等几天才会遇到第一个严格更高温度,没有则为 0;相同温度不计,空数组返回 []。
* 示例:temperatures=[70,70,71] 返回 [2,1,0]:前两天分别等 2 天、1 天,最后一天没有更高温度。
*/
function dailyTemperatures(temperatures) {}
console.log(dailyTemperatures([73, 74, 75, 71, 69, 72, 76, 73])); // 预期:[1, 1, 4, 2, 1, 1, 0, 0]
console.log(dailyTemperatures([70, 70, 71])); // 预期:[2, 1, 0]
console.log(dailyTemperatures([3, 2, 1])); // 预期:[0, 0, 0]
console.log(dailyTemperatures([])); // 预期:[]解题思路与实现
展开解题思路
单调栈只保存尚无答案的索引;遇到更高温度时弹出并填入距离。
function dailyTemperatures(temperatures) {
const answer = Array(temperatures.length).fill(0);
const stack = [];
for (let i = 0; i < temperatures.length; i += 1) {
while (
stack.length > 0 &&
temperatures[i] > temperatures[stack[stack.length - 1]]
) {
const previous = stack.pop();
answer[previous] = i - previous;
}
stack.push(i);
}
return answer;
}
// 三组以上可直接运行的验证。
console.log(dailyTemperatures([73, 74, 75, 71, 69, 72, 76, 73])); // 预期:[1, 1, 4, 2, 1, 1, 0, 0]
console.log(dailyTemperatures([70, 70, 71])); // 预期:[2, 1, 0]
console.log(dailyTemperatures([3, 2, 1])); // 预期:[0, 0, 0]
console.log(dailyTemperatures([])); // 预期:[]
function dailyTemperatures(temperatures) {
const answer = Array(temperatures.length).fill(0);
const stack = [];
for (let i = 0; i < temperatures.length; i += 1) {
while (
stack.length > 0 &&
temperatures[i] > temperatures[stack[stack.length - 1]]
) {
const previous = stack.pop();
answer[previous] = i - previous;
}
stack.push(i);
}
return answer;
}
// 三组以上可直接运行的验证。
console.log(dailyTemperatures([73, 74, 75, 71, 69, 72, 76, 73])); // 预期:[1, 1, 4, 2, 1, 1, 0, 0]
console.log(dailyTemperatures([70, 70, 71])); // 预期:[2, 1, 0]
console.log(dailyTemperatures([3, 2, 1])); // 预期:[0, 0, 0]
console.log(dailyTemperatures([])); // 预期:[]
时间复杂度:O(n)。每个索引最多压栈一次、弹栈一次。
空间复杂度:O(n)。答案数组与未解决索引栈最多各占 n 项。