Problem Description
Given an integer array nums and a non-negative integer k, find the maximum length of a subsequence of nums (not necessarily contiguous) that is "good". A subsequence is defined as good if there are at most k indices i (in the subsequence’s order) for which the adjacent elements differ (i.e. seq[i] != seq[i+1]). In other words, you may switch between different numbers at most k times while building the subsequence.
Key Insights
- We can pick elements non-contiguously; only the relative order matters.
- The “good” subsequence allows at most k transitions between different consecutive values.
- When adding an element equal to the previous one, no new transition is introduced.
- When adding a different element, we “spend” one of the allowed k changes.
- Dynamic programming with memoization can efficiently explore decisions at each index.
Space and Time Complexity
Time Complexity: O(n * (k+1) * U) where n is the length of nums and U is the number of unique states for the last picked value (at most n distinct numbers)
Space Complexity: O(n * (k+1) * U) due to the memoization cache and recursion call stack
Solution
We use a recursive dynamic programming approach with memoization. The state is defined by:
• i: the current index in nums being considered
• last: the last number included in our subsequence (or a sentinel value if none has been picked)
• rem: the remaining allowed transitions (initially equal to k)
At each step:
- We decide to skip nums[i] and move on.
- Or we decide to take nums[i]:
- If no element has been picked (last is undefined) or nums[i] equals the last picked element, then no extra transition is used.
- If nums[i] is different from last and we have at least one allowed transition rem > 0, we take it and decrement rem.
- We choose the option that maximizes the length of the subsequence.
By memoizing each state (i, last, rem), we ensure that every unique subproblem is computed only once.