题目描述

✅ 197. 上升的温度

image-20260929090845331

image-20260929090845431

题意分析

找出温度严格高于日历上前一天的记录,返回升温当天的 id。如果表里没有前一天的记录,这一天就没有可比较对象,不应出现在结果中。

id 只是记录标识,不代表时间先后;即使按日期排序,相邻两行之间也可能隔了多天,因此必须按日期恰好相差一天来配对。

解法:日期自连接

核心思路

[!blue]

给同一张 Weather 表设置两个别名:today 表示正在检查的当天记录,yesterday 表示要寻找的前一天记录。两侧的角色先确定,日期条件和温度比较方向也就明确了。

用 DATE_SUB(today.recordDate, INTERVAL 1 DAY) 得到真正的前一天日期,再让 yesterday.recordDate 与它相等。日期函数会按日历规则处理跨月、跨年等边界,不需要自己计算年月日。

内连接只保留找到了昨天的记录,没有昨天数据的行会自然排除。题目保证日期不重复,所以每条今天的记录最多配到一条昨天,不会因为连接产生重复答案。

最后保留 today.temperature > yesterday.temperature 的行,并返回 today.id。配对解决的是“有没有前一天”,温度条件解决的是“是否真的升温”,两者缺一不可。

解题步骤

  1. 用 today、yesterday 两个别名引用 Weather 表。
  2. 将 yesterday.recordDate 与当天减一天的日期作等值连接。
  3. 在匹配成功的记录对中,筛选今天温度严格大于昨天温度的行。
  4. 输出 today.id,无需按日期或编号额外排序。

代码实现

-- today 与日历上的前一天等值连接,再比较温度。
SELECT today.id
FROM Weather AS today
JOIN Weather AS yesterday
ON yesterday.recordDate = DATE_SUB(today.recordDate, INTERVAL 1 DAY)
WHERE today.temperature > yesterday.temperature;

复杂度分析

设记录数为 n,实际开销由索引和数据库执行计划决定。

  • 时间复杂度:若通过日期索引为每条记录查找前一天,通常可按 $O(n\log(n+1))$ 估算;朴素的两表嵌套扫描最坏为 $O(n^2)$。
  • 空间复杂度:取决于连接所需的缓冲和结果处理方式,不能仅由 SQL 文本确定固定值。

关键点总结

[!green]

  • 前一天是日历关系,必须用日期配对,不能用记录位置或 id 代替。
  • 内连接自然排除缺少昨天记录的日期,严格大于排除温度持平的情况。
  • yesterday.recordDate 保留为原列,为已有日期索引提供等值查找的机会。

易错点总结

[!yellow]

  • 按 id 相差一连接:编号不保证与日期连续对应。
  • 只比较日期排序后的上一行:上一行可能是几天前,缺失日期会造成误判。
  • 把日期当普通整数减一:无法正确处理跨月或跨年的日历边界。
  • 温度使用大于等于:温度不变不算上升。
  • 输出 yesterday.id:题目要的是升温当天,应该返回 today.id。

相似题目

题目 难度 关联与区别
180. 连续出现的数字 中等 同样比较相邻记录,本题要求日期恰好相差一天,不能简单假设id相邻就是相邻日期。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2022/23785682
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!