Problem
You are given an integer array arr
of length n
that represents a permutation of the integers in the range [0, n - 1]
.
We split arr
into some number of chunks (i.e., partitions), and individually sort each chunk. After concatenating them, the result should equal the sorted array.
Return the largest number of chunks we can make to sort the array.
Examples
Example 1:
|
|
Example 2:
|
|
Constraints
n == arr.length
1 <= n <= 10
0 <= arr[i] < n
- All the elements of
arr
are unique.
Solution
Video explanation
Here is the video explaining this method in detail. Please check it out:
Method 1 - Naive
One of the naive approaches would be to try putting a partition at every possible index in the array. For each partition configuration, sort the resulting chunks and concatenate them. Finally, check if the concatenated result matches the expected sorted array.
The time complexity of this is O(2^n * n log n)
:
- Generating all partitions results in
O(2^(n-1))
combinations. - Sorting each partition configuration takes
O(n log n)
. - Comparing with the expected sorted array takes
O(n)
. - Overall time complexity:
O(2^n * n log n)
.
Method 2 - Using Prefix sum
To solve the problem of dividing the array into the maximum number of chunks that when individually sorted and concatenated result in a sorted array, we can leverage the concept of prefix sums. The prefix sum helps determine valid chunks by comparing the sum of the elements up to a certain index with the sum of the indices up to the same index. If these sums match, we can conclude that all elements up to that index can form a valid chunk.
Approach
Here is the approach:
- Initialize Variables:
arr_sum
to store the sum of the array elements up to the current index.ideal_sum
to store the sum of the indices up to the current index.chunks
to count the number of valid chunks.
- Iterate through the Array:
- Update
arr_sum
andideal_sum
at each index. - Compare
arr_sum
andideal_sum
. When they are equal, incrementchunks
.
- Update
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)
Method 3 - Track the Max so Far
We can partition the array into contiguous segments such that each chunk, once sorted, can be concatenated to form the sorted array.
|
|
Lets look at max array:
|
|
When max[index] == index
, all values before index
must be smaller than max[index]
. This forms a continuous chunk as the array contains distinct numbers ranging from 0
to arr.length - 1
.
Since the numbers in the array only range from [0, 1, ..., arr.length - 1]
, the greatest number of elements smaller than arr[k]
would be arr[k] - 1
, which are [0, 1, ..., arr[k] - 1]
. Therefore, if arr[k]
is the maximum value in [arr[0], arr[1], ..., arr[k]]
, all k-1
preceding numbers must lie within [0, 1, ..., arr[k] - 1]
, forming a continuous sequence.
|
|
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 4 - No need of using max array
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)