Split Array into Consecutive Subsequences - Solution & Explanation
Problem Statement
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
3or 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).
Example 1:
Input: nums = [1,2,3,3,4,5] Output: true Explanation: nums can be split into the following subsequences: [1,2,3,3,4,5] --> 1, 2, 3 [1,2,3,3,4,5] --> 3, 4, 5
Example 2:
Input: nums = [1,2,3,3,4,4,5,5] Output: true Explanation: nums can be split into the following subsequences: [1,2,3,3,4,4,5,5] --> 1, 2, 3, 4, 5 [1,2,3,3,4,4,5,5] --> 3, 4, 5
Example 3:
Input: nums = [1,2,3,4,4,5] Output: false Explanation: It is impossible to split nums into consecutive increasing subsequences of length 3 or more.
Constraints:
1 <= nums.length <= 104-1000 <= nums[i] <= 1000numsis sorted in non-decreasing order.
Approach Overview
Problem Overview: You receive a sorted integer array and must determine whether it can be split into one or more subsequences of consecutive integers, each with length at least 3. Every element must belong to exactly one subsequence.
Approach 1: Greedy Hash Map (Iterative) (Time: O(n), Space: O(n))
This approach uses two hash maps. The first map freq tracks how many times each number appears. The second map need tracks how many subsequences are currently waiting for a specific next number. Iterate through the array and try to append the current number to an existing subsequence if need[num] > 0. If not possible, attempt to start a new subsequence using num, num+1, num+2 by checking their counts in freq. If neither option works, forming valid subsequences is impossible. The greedy insight: always extend an existing subsequence before creating a new one. This avoids leaving short sequences that cannot reach length 3. This method heavily relies on fast hash table lookups and is the standard optimal solution using a greedy strategy.
Approach 2: Min-Heap Tracking Subsequence Lengths (Time: O(n log n), Space: O(n))
Another strategy maintains active subsequences using a min-heap. Each heap entry represents a subsequence ending at a specific value and stores its length. When processing a number, check if there is a subsequence ending at num - 1. If one exists, extend the shortest such subsequence (pop from heap, increment length, push back with new end). If none exists, start a new subsequence of length 1. After processing all numbers, verify that every subsequence has length at least 3. The heap ensures the shortest subsequence grows first, which prevents invalid short chains. This technique demonstrates how a priority queue can manage competing subsequences efficiently.
Approach 3: Recursive Backtracking (Time: Exponential worst-case, Space: O(n))
A recursive solution tries to build subsequences by deciding where each number should go. Maintain partial subsequences and recursively attempt to extend them or start new ones. Each recursive branch chooses a subsequence whose last element is num - 1 or creates a new sequence. Pruning occurs when a sequence cannot possibly reach length 3. While conceptually simple, the branching factor grows quickly, leading to exponential time in the worst case. This method mainly helps illustrate the problem constraints before discovering the greedy pattern.
Recommended for interviews: The greedy hash map solution is what interviewers expect. It demonstrates recognition of the greedy invariant (extend existing subsequences first) and efficient use of frequency counting with hash maps. Discussing the heap method also shows strong understanding of alternative designs, but the O(n) greedy approach is considered the optimal answer.
Approach 1: Approach 1: Iterative Solution
The first approach involves using an iterative method to solve the problem. This generally involves using loops to traverse and manage the input data while making use of auxiliary data structures to optimize the solution.
This C program demonstrates a simple iteration over an array, printing each element. Replace or extend the logic inside the loop as needed for your specific problem.
Complexity
Time Complexity: O(n), where n is the number of elements in the array.
Space Complexity: O(1), as it uses constant space.
Approach 2: Approach 2: Recursive Solution
The second approach uses recursion to solve the given problem, which can simplify problems with a clear recursive structure. This involves a base case and a recursive call that processes a subset of the data.
This C function demonstrates recursive traversal of an array. It prints each element until the base case (end of the array) is reached.
Complexity
Time Complexity: O(n), due to n recursive calls.
Space Complexity: O(n), for the recursion call stack.
Approach 3: Default Approach
Try this approach in the editor →Complexity Comparison
| Approach | Complexity |
|---|---|
| Approach 1: Iterative Solution | Time Complexity: O(n), where n is the number of elements in the array. |
| Approach 2: Recursive Solution | Time Complexity: O(n), due to n recursive calls. |
| Default Approach | — |
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Greedy with Hash Maps | O(n) | O(n) | Best general solution. Optimal for sorted arrays with frequent lookups. |
| Min-Heap Subsequence Tracking | O(n log n) | O(n) | Useful when explicitly tracking subsequence lengths or demonstrating heap usage. |
| Recursive Backtracking | Exponential | O(n) | Educational approach to explore all placements before discovering greedy optimization. |
Video Solution
Arrays | Leetcode 659 | Split Array Into Consecutive Subsequences • Nideesh Terapalli • 21,993 views views
Watch 9 more video solutions →Frequently Asked Questions
Is Split Array into Consecutive Subsequences easy or hard?
Split Array into Consecutive Subsequences Python/Java solution
How to solve Split Array into Consecutive Subsequences in O(n)?
What is the best approach for Split Array into Consecutive Subsequences?
Is Split Array into Consecutive Subsequences asked at Google/Amazon/Meta?
What data structure is used in Split Array into Consecutive Subsequences?
What is the time complexity of Split Array into Consecutive Subsequences?
Ready to solve this problem?
Practice Split Array into Consecutive Subsequences with our built-in code editor and test cases.
Practice on FleetCodeTable of Contents
Practice this problem
Open in Editor