LeetCodee

376. Wiggle Subsequence

Jump to Solution: Python Java C++ JavaScript C#

Problem Description

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.

Example 1:

Input: nums = [1,7,4,9,2,5]
Output: 6
Explanation: The entire sequence is a wiggle sequence with differences (6,-3,5,-7,3).

Example 2:

Input: nums = [1,17,5,10,13,15,10,5,16,8]
Output: 7
Explanation: There are several subsequences that achieve this length.
One is [1,17,10,13,10,16,8] with differences (16,-7,3,-3,6,-8).

Example 3:

Input: nums = [1,2,3,4,5,6,7,8,9]
Output: 2

Constraints:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000

Solution

Python Solution

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return len(nums)
        
        # Initialize the lengths for sequences ending with up and down differences
        up = down = 1
        
        # Iterate through the array starting from index 1
        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                # Current number is greater than previous
                # up can be extended from previous down
                up = down + 1
            elif nums[i] < nums[i - 1]:
                # Current number is smaller than previous
                # down can be extended from previous up
                down = up + 1
            # If numbers are equal, up and down remain unchanged
        
        return max(up, down)

Time Complexity: O(n)

Where n is the length of the input array. We only need to iterate through the array once.

Space Complexity: O(1)

Only uses two variables to track the lengths.

Java Solution

class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length < 2) {
            return nums.length;
        }
        
        // Initialize the lengths for sequences ending with up and down differences
        int up = 1;
        int down = 1;
        
        // Iterate through the array starting from index 1
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) {
                // Current number is greater than previous
                // up can be extended from previous down
                up = down + 1;
            } else if (nums[i] < nums[i - 1]) {
                // Current number is smaller than previous
                // down can be extended from previous up
                down = up + 1;
            }
            // If numbers are equal, up and down remain unchanged
        }
        
        return Math.max(up, down);
    }
}

Time Complexity: O(n)

Where n is the length of the input array. We only need to iterate through the array once.

Space Complexity: O(1)

Only uses two variables to track the lengths.

C++ Solution

class Solution {
public:
    int wiggleMaxLength(vector& nums) {
        if (nums.size() < 2) {
            return nums.size();
        }
        
        // Initialize the lengths for sequences ending with up and down differences
        int up = 1;
        int down = 1;
        
        // Iterate through the array starting from index 1
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i] > nums[i - 1]) {
                // Current number is greater than previous
                // up can be extended from previous down
                up = down + 1;
            } else if (nums[i] < nums[i - 1]) {
                // Current number is smaller than previous
                // down can be extended from previous up
                down = up + 1;
            }
            // If numbers are equal, up and down remain unchanged
        }
        
        return max(up, down);
    }
};

Time Complexity: O(n)

Where n is the length of the input array. We only need to iterate through the array once.

Space Complexity: O(1)

Only uses two variables to track the lengths.

JavaScript Solution

/**
 * @param {number[]} nums
 * @return {number}
 */
var wiggleMaxLength = function(nums) {
    if (nums.length < 2) {
        return nums.length;
    }
    
    // Initialize the lengths for sequences ending with up and down differences
    let up = 1;
    let down = 1;
    
    // Iterate through the array starting from index 1
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] > nums[i - 1]) {
            // Current number is greater than previous
            // up can be extended from previous down
            up = down + 1;
        } else if (nums[i] < nums[i - 1]) {
            // Current number is smaller than previous
            // down can be extended from previous up
            down = up + 1;
        }
        // If numbers are equal, up and down remain unchanged
    }
    
    return Math.max(up, down);
};

Time Complexity: O(n)

Where n is the length of the input array. We only need to iterate through the array once.

Space Complexity: O(1)

Only uses two variables to track the lengths.

C# Solution

public class Solution {
    public int WiggleMaxLength(int[] nums) {
        if (nums.Length < 2) {
            return nums.Length;
        }
        
        // Initialize the lengths for sequences ending with up and down differences
        int up = 1;
        int down = 1;
        
        // Iterate through the array starting from index 1
        for (int i = 1; i < nums.Length; i++) {
            if (nums[i] > nums[i - 1]) {
                // Current number is greater than previous
                // up can be extended from previous down
                up = down + 1;
            } else if (nums[i] < nums[i - 1]) {
                // Current number is smaller than previous
                // down can be extended from previous up
                down = up + 1;
            }
            // If numbers are equal, up and down remain unchanged
        }
        
        return Math.Max(up, down);
    }
}

Time Complexity: O(n)

Where n is the length of the input array. We only need to iterate through the array once.

Space Complexity: O(1)

Only uses two variables to track the lengths.

Approach Explanation

The solution uses dynamic programming with space optimization to find the longest wiggle subsequence:

  1. Key Insights:
    • Track two possible states
    • Only need previous state
    • Alternating pattern
    • Greedy approach works
  2. Algorithm Steps:
    • Initialize up and down lengths
    • Process array sequentially
    • Update based on differences
    • Return maximum length

Implementation Details:

  • Handle base cases
  • Track two states efficiently
  • Compare adjacent elements
  • Maintain optimal substructure

Optimization Insights:

  • Space optimization
  • Single pass solution
  • No need for extra storage
  • Constant space complexity

Edge Cases:

  • Empty array
  • Single element
  • Equal adjacent elements
  • Monotonic sequence