题目描述
相邻差值正负交替的序列叫摆动序列。求最长摆动子序列长度。
nums = [1, 7, 4, 9, 2, 5]
输出 = 6 (本身就是摆动的)
思路解析
把每个子序列都挑出来、逐一检查是不是一上一下交替,共 2ⁿ 个,指数级。但其实根本不用枚举——最长摆动子序列的长度,就等于原序列里「方向转折」的次数 + 1,一遍扫描数转折就行。
up 表示目前以「上升」结尾的最长摆动长度,down 表示以「下降」结尾的。上升时 up = down + 1,下降时 down = up + 1。答案取两者最大。
起点:从第一个数开始,up 和 down 都是 1。
i=1 · 7>1 上升:7 比前一个 1 大,是上升。up = down + 1 = 2。
i=2 · 4<7 下降:4 比 7 小,是下降。down = up + 1 = 3。
i=3 · 9>4 上升:9 比 4 大,上升。up = down + 1 = 4。
i=4 · 2<9 下降:2 比 9 小,下降。down = up + 1 = 5。
i=5 · 5>2 上升:5 比 2 大,上升。up = down + 1 = 6。
答案:答案 = max(up, down) = 6。(如果相邻两个数相等,up/down 都不变,自动跳过)
摆动序列的长度 = 转折点个数 + 1。把「方向」当状态来维护,这是贪心/状态机的常见套路。
参考代码(Python)
Python
1if len(nums) < 2: return len(nums)
2up = down = 1
3for i in range(1, len(nums)):
4 if nums[i] > nums[i-1]: up = down + 1 # 上升
5 elif nums[i] < nums[i-1]: down = up + 1 # 下降
6 # 相等则都不变
7return max(up, down)复杂度分析
- 时间复杂度:O(n) —— 一遍扫描
- 空间复杂度:O(1) —— 两个变量
套路模板
记住骨架:两个状态此消彼长、只在方向改变时 +1。买卖股票II「只在上涨段累加」也是这种一遍状态贪心。
Python
1# 把「方向 / 状态」当变量,一遍扫描交替更新
2up = down = 1
3for i in range(1, n):
4 if nums[i] > nums[i-1]: up = down + 1 # 升:接在降后面
5 elif nums[i] < nums[i-1]: down = up + 1 # 降:接在升后面
6 # 相等:两者都不动
7return max(up, down)易错点
- ❌ 相等时也更新 up/down → ✅ 相等(==)时两者都不变(相等不构成上升或下降)
- ❌ 长度 <2 不特判 → ✅ 先处理 len<2 直接返回长度(单元素也是合法摆动序列)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。