Problem
A wiggle sequence is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.
- For example,
[1, 7, 4, 9, 2, 5]
is a wiggle sequence because the differences(6, -3, 5, -7, 3)
alternate between positive and negative. - In contrast,
[1, 4, 7, 2, 5]
and[1, 7, 4, 5, 5]
are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.
A subsequence is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.
Given an integer array nums
, return the length of the longest wiggle subsequence of nums
.
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Solution
Method 1 - Dynamic Programming DP
At each index in the array, the value can be in one of three states:
- “up” if
nums[i] > nums[i-1]
, - “down” if
nums[i] < nums[i-1]
, - or “equal” if
nums[i] == nums[i-1]
.
We use two arrays, up[]
and down[]
, to track the maximum wiggle subsequence length at each position.
If the current value is greater than the previous, update up[i] = down[i-1] + 1
and keep down[i]
unchanged.
If it’s less, set down[i] = up[i-1] + 1
and leave up[i]
as before.
If the values are equal, both arrays remain the same as the previous index.
|
|
Complexity
- ⏰ Time complexity:
O(n)
. You iterate through the array once, updating theup
anddown
arrays at each step. - 🧺 Space complexity:
O(n)
. Two arrays of sizen
(up[]
anddown[]
) are used to store the results for each position.
Method 2 - Space Optimized DP
Intuition
Instead of keeping track of the entire history, we only need to know the length of the longest wiggle subsequence ending with an “up” or a “down” at the previous step. This allows us to use two variables instead of arrays.
Approach
- Initialize two variables,
up
anddown
, both set to 1. - Iterate through the array from the second element:
- If the current number is greater than the previous, set
up = down + 1
. - If the current number is less than the previous, set
down = up + 1
. - If equal, do nothing.
- If the current number is greater than the previous, set
- At the end, return the maximum of
up
anddown
.
Code
|
|
Complexity
- ⏰ Time complexity:
O(n)
. Single pass through the array. - 🧺 Space complexity:
O(1)
. Only two variables are used.
Method 3 - Greedy
Intuition
A wiggle subsequence alternates between increasing and decreasing. We only need to count the number of times the direction of the difference between consecutive elements changes.
Approach
- Initialize a counter (starting at 1) and a variable to track the previous difference.
- Iterate through the array:
- For each element, calculate the difference with the previous element.
- If the difference changes sign (from positive to negative or vice versa), increment the counter and update the previous difference.
- Return the counter as the length of the longest wiggle subsequence.
Code
|
|
Complexity
- ⏰ Time complexity:
O(n)
. Single pass through the array. - 🧺 Space complexity:
O(1)
. Only a few variables are used.