Problem
You are given an integer array nums
that is sorted in non-decreasing order.
Determine if it is possible to split nums
into one or more subsequences such that both of the following conditions are true:
- Each subsequence is a consecutive increasing sequence (i.e. each integer is exactly one more than the previous integer).
- All subsequences have a length of
3
or more.
Return true
if you can split nums
according to the above conditions, or false
otherwise.
A subsequence of an array is a new array that is formed from the original array by deleting some (can be none) of the elements without disturbing the relative positions of the remaining elements. (i.e., [1,3,5]
is a subsequence of [1,2,3,4,5]
while [1,3,2]
is not).
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Solution
Method 1 - Using Hashing
Intuition
The main idea is to use two hash maps: one (freq
) to count the remaining occurrences of each number, and another (end
) to track how many subsequences end at a given number. For each number, we try to append it to an existing subsequence ending at num-1
(by checking end[num-1]
), or start a new subsequence with num, num+1, num+2
(by checking freq[num+1]
and freq[num+2]
). If neither is possible, we return false. This greedy approach ensures all subsequences are at least length 3 and consecutive.
Approach
- Count the frequency of each number in
nums
using a hash mapfreq
. - Iterate through
nums
:- If
freq[num] == 0
, continue (already used). - If there is a subsequence ending at
num-1
(end[num-1] > 0
):- Decrement
end[num-1]
and incrementend[num]
.
- Decrement
- Else, if
freq[num+1] > 0
andfreq[num+2] > 0
:- Use
num
,num+1
,num+2
to start a new subsequence, decrement their frequencies, and incrementend[num+2]
.
- Use
- Else, return false.
- Always decrement
freq[num]
after using it.
- If
- If all numbers are used successfully, return true.
Dry Run
Let’s dry run the algorithm for nums = [1,2,3,3,4,5]
:
- Initial
freq
: {1:1, 2:1, 3:2, 4:1, 5:1},end
: {} - Process 1: No subsequence to extend, can start new with 2,3. Use 1,2,3. Update:
freq
: {1:0, 2:0, 3:1, 4:1, 5:1},end
: {3:1} - Process 2: Already used.
- Process 3: Can extend subsequence ending at 2 (none), can start new with 4,5. Use 3,4,5. Update:
freq
: {1:0, 2:0, 3:0, 4:0, 5:0},end
: {3:1, 5:1} - All numbers used, return True.
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the length ofnums
, since each number is processed at most twice. - 🧺 Space complexity:
O(n)
, for the hash maps storing frequencies and subsequence ends.
Code
|
|
|
|
|
|
Method 2 - Without Using Extra Space
Intuition
Instead of using hash maps, we can use pointers and counters to track the lengths of possible subsequences as we scan through the sorted array. By grouping identical numbers and counting how many new subsequences can be started or extended, we can greedily ensure all subsequences are at least length 3. This approach leverages the sorted property of the array and only uses a constant number of variables for each group.
Approach
- Use pointers to scan through
nums
and group identical numbers, counting their frequency (cnt
). - Track the number of subsequences ending with lengths 1 (
prev1
), 2 (prev2
), and 3+ (prev3
) for the previous number. - For each group of the current number:
- If the current number is not consecutive to the previous, all previous subsequences must be of length 3 or more (
prev1 == 0 && prev2 == 0
). - Calculate how many subsequences can be extended and how many new ones must be started.
- If not enough numbers to extend all previous subsequences of length 1 or 2, return false.
- Update counters for the next iteration.
- If the current number is not consecutive to the previous, all previous subsequences must be of length 3 or more (
- After processing all numbers, ensure no subsequence of length less than 3 remains.
Dry Run
For nums = [1,2,3,3,4,5]
:
- Group 1: cnt=1, start 1 subsequence of length 1
- Group 2: cnt=1, extend previous length 1 to length 2
- Group 3: cnt=2, extend previous length 2 to length 3, start 1 new subsequence of length 1
- Group 4: cnt=1, extend previous length 1 to length 2
- Group 5: cnt=1, extend previous length 2 to length 3
- All subsequences are length 3 or more, return True
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the length ofnums
, as we scan the array once. - 🧺 Space complexity:
O(1)
, only a constant number of counters are used.
Code
|
|
|
|
|
|