下面是两个函数的完整代码,包含详细注释、函数含义和物理意义解释。这两个函数分别用于:
✅ 1. dailyTemperatures(temperatures) 功能:
计算每一天之后需要等待多少天才能遇到一个更温暖的天气(即温度更高的日子)。
物理意义:
这是一个经典的 “每日温度”问题,模拟了现实生活中人们关心“明天是否更热”的问题。它也可以被看作是一个 “下一个更大元素” 的变种问题。
实现方式:
使用了一个 栈(stack) 来保存温度的索引,通过从后往前遍历数组的方式,维护一个单调递增的栈结构。
✅ 2. sliding_window_max(nums, k=3) 功能:
找出每个大小为 k 的滑动窗口中的最大值。
物理意义:
这是数据流中常见的处理任务,例如监控系统每5分钟取一次CPU占用率的最大值、股票价格波动分析等场景。它是典型的 滑动窗口最大值问题。
实现方式:
使用了一个 单调队列(Monotonic Queue) 来维护当前窗口中可能成为最大值的元素索引。这个队列始终保持递减顺序。
def dailyTemperatures(temperatures):
"""
计算每天之后需要等待多少天才会有更高温度。
参数:
temperatures (List[int]): 温度列表,表示每天的温度
返回:
List[int]: 每个位置i的答案表示在第i天之后要等几天才能遇到更高温度;
如果之后没有更高温度,则对应结果为0。
物理意义:
解决“下一个更高温度”的问题,常用于天气预报或类似序列分析。
使用栈维护“尚未找到更高温度”的日期索引,实现O(n)时间复杂度。
"""
n = len(temperatures)
sk = [] # 栈,保存的是索引
ans = [0] * n # 答案数组
# 从后往前遍历
for i in range(n - 1, -1, -1):
# 如果当前温度 >= 栈顶温度,弹出栈顶(说明这些天不会是答案)
while sk and temperatures[i] >= temperatures[sk[-1]]:
sk.pop()
if sk:
# 栈顶是第一个比当前温度高的日子
ans[i] = sk[-1] - i
else:
ans[i] = 0
sk.append(i) # 把当前索引压入栈
return ans
# 示例测试
temps = [73, 74, 75, 71, 69, 72, 76, 73]
print("每日温度问题结果:", dailyTemperatures(temps))
# 输出: [1, 1, 4, 2, 1, 1, 0, 0]
def sliding_window_max(nums, k=3):
"""
找出每个大小为k的滑动窗口中的最大值。
参数:
nums (List[int]): 整数数组
k (int): 滑动窗口大小,默认为3
返回:
List[int]: 每个窗口内的最大值组成的列表
物理意义:
常见于实时数据分析、信号处理、金融数据统计等领域。
使用“单调队列”思想优化查找过程,避免暴力枚举,提升效率到O(n)。
实现思路:
- 维护一个双端队列 dq,保存的是元素索引,且这些索引对应的值保持递减顺序。
- 队首始终是当前窗口最大值的索引。
- 当窗口滑动时,移除过期索引和不合适的候选值。
"""
if not nums or k <= 0:
return []
n = len(nums)
result = []
dq = [] # 用普通列表模拟双端队列,保存索引
for i in range(n):
# 移除超出窗口范围的索引(只检查队首)
while dq and dq[0] < i - k + 1:
dq.pop(0) # 模拟 popleft()
# 移除比当前元素小的所有元素(保持单调递减)
while dq and nums[dq[-1]] < nums[i]:
dq.pop()
# 将当前元素索引加入队列
dq.append(i)
# 当窗口长度达到k时,记录当前最大值
if i >= k - 1:
result.append(nums[dq[0]])
return result
# 示例测试
a = [1, 3, -1, 5, 3, 6, 7]
k = 3
print("滑动窗口最大值问题结果:", sliding_window_max(a, k))
# 输出: [3, 5, 5, 6, 7]
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com