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 theupanddownarrays 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,
upanddown, 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
upanddown.
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.