1.題目介紹
題目地址(376. 擺動序列 - 力扣(LeetCode))
https://leetcode.cn/problems/wiggle-subsequence/
題目描述
如果連續數字之間的差嚴格地在正數和負數之間交替,則數字序列稱為 擺動序列 。第一個差(如果存在的話)可能是正數或負數。僅有一個元素或者含兩個不等元素的序列也視作擺動序列。
-
例如,
[1, 7, 4, 9, 2, 5]
是一個 擺動序列 ,因為差值(6, -3, 5, -7, 3)
是正負交替出現的。 - 相反,
[1, 4, 7, 2, 5]
和[1, 7, 4, 5, 5]
不是擺動序列,第一個序列是因為它的前兩個差值都是正數,第二個序列是因為它的最後一個差值為零。
子序列 可以透過從原始序列中刪除一些(也可以不刪除)元素來獲得,剩下的元素保持其原始順序。
給你一個整數陣列 nums
,返回 nums
中作為 擺動序列 的 最長子序列的長度 。
示例 1:
輸入:nums = [1,7,4,9,2,5] 輸出:6 解釋:整個序列均為擺動序列,各元素之間的差值為 (6, -3, 5, -7, 3) 。
示例 2:
輸入:nums = [1,17,5,10,13,15,10,5,16,8] 輸出:7 解釋:這個序列包含幾個長度為 7 擺動序列。 其中一個是 [1, 17, 10, 13, 10, 16, 8] ,各元素之間的差值為 (16, -7, 3, -3, 6, -8) 。
示例 3:
輸入:nums = [1,2,3,4,5,6,7,8,9] 輸出:2
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
進階:你能否用 O(n)
時間複雜度完成此題?
2.題解
2.1 動態規劃
思路
這裡我們使用動態規劃,主要明白子序列可能所處的幾種狀態,和它的狀態轉移方程:
1.上升序列up[i], 表示取範圍在[0,i]的上升子序列的最大元素個數
2.下降序列down[i],表示取範圍在[0,i]的下降子序列的最大元素個數
狀態轉移方程:
我們先來討論上升序列情況,由於當前元素nums[i]和nums[i-1]的大小關係,會影響到序列子元素的選擇,所以我們分情況來討論:
1.nums[i] > nums[i-1]
這個時候,up[i]可以由up[i-1]或者down[i-1]轉化而來
1)如果對於up[i-1], 由於up[i]最後一個元素可以選擇nums[i-1],也可以選擇nums[i],但二者不能同時選擇,其實是平替關係
即 up[i] = up[i-1];
2)如果對於down[i-1],由於down[i-1]最後一個元素可能不是nums[i-1],而是nums[j],
且存在nums[j] > nums[i]的情況下,所以我們需要討論一下是否能找出一種匹配情況?
其實很簡單,down[i-1]最後一個元素不是nums[i-1],且nums[j] > nums[i] > nums[i-1]
那麼我將
最終結果是:
\(\begin{aligned}&up[i]=\begin{cases}up[i-1],&nums[i]\leq nums[i-1]\\\max(up[i-1],down[i-1]+1),&nums[i]>nums[i-1]\end{cases}\\&down[i]=\begin{cases}down[i-1],&nums[i]\geq nums[i-1]\\\max(up[i-1]+1,down[i-1]),&nums[i]<nums[i-1]\end{cases}\end{aligned}\)
程式碼
- 語言支援:C++
C++ Code:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n < 2) return n;
vector<int> up(n), down(n);
up[0] = 1; down[0] = 1;
for(int i = 1; i < n; i++){
if(nums[i] > nums[i-1]){
up[i] = max(up[i-1], down[i-1] + 1);
down[i] = down[i-1];
}else if(nums[i] < nums[i-1]){
up[i] = up[i-1];
down[i] = max(up[i-1] + 1, down[i-1]);
}else{
up[i] = up[i - 1];
down[i] = down[i-1];
}
}
return max(up[n-1], down[n-1]);
}
};
複雜度分析
令 n 為陣列長度。
- 時間複雜度:\(O(n)\)
- 空間複雜度:\(O(n)\)