编码母题 / 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([])); // 预期:[]

解题思路与实现

展开解题思路

单调栈只保存尚无答案的索引;遇到更高温度时弹出并填入距离。

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 项。

下载原始 JS 文件