Partition Array into Disjoint Intervals
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given an integer array nums, partition it into two (contiguous) subarrays
left and right so that:
- Every element in
leftis less than or equal to every element inright. leftandrightare non-empty.lefthas the smallest possible size.
Return the length ofleft after such a partitioning.
Test cases are generated such that partitioning exists.
Examples
Example 1
Input: nums = [5,0,3,8,6]
Output: 3
Explanation: left = [5,0,3], right = [8,6]
Example 2
Input: nums = [1,1,1,0,6,12]
Output: 4
Explanation: left = [1,1,1,0], right = [6,12]
Constraints
2 <= nums.length <= 10^50 <= nums[i] <= 10^6- There is at least one valid answer for the given input.
Solution
Method 1 – Prefix Max and Suffix Min
Intuition
To ensure every element in left is less than or equal to every element in right, we can precompute the maximum value up to each index from the left and the minimum value from each index to the right. The smallest partition point is where the left max is less than or equal to the right min.
Approach
- Compute an array
left_maxwhereleft_max[i]is the maximum ofnums[0..i]. - Compute an array
right_minwhereright_min[i]is the minimum ofnums[i..n-1]. - Find the smallest index
iwhereleft_max[i] <= right_min[i+1]. - Return
i+1as the length ofleft.
Code
C++
class Solution {
public:
int partitionDisjoint(vector<int>& nums) {
int n = nums.size();
vector<int> left_max(n), right_min(n);
left_max[0] = nums[0];
for (int i = 1; i < n; ++i)
left_max[i] = max(left_max[i-1], nums[i]);
right_min[n-1] = nums[n-1];
for (int i = n-2; i >= 0; --i)
right_min[i] = min(right_min[i+1], nums[i]);
for (int i = 0; i < n-1; ++i) {
if (left_max[i] <= right_min[i+1])
return i+1;
}
return n;
}
};
Go
func partitionDisjoint(nums []int) int {
n := len(nums)
leftMax := make([]int, n)
rightMin := make([]int, n)
leftMax[0] = nums[0]
for i := 1; i < n; i++ {
if nums[i] > leftMax[i-1] {
leftMax[i] = nums[i]
} else {
leftMax[i] = leftMax[i-1]
}
}
rightMin[n-1] = nums[n-1]
for i := n-2; i >= 0; i-- {
if nums[i] < rightMin[i+1] {
rightMin[i] = nums[i]
} else {
rightMin[i] = rightMin[i+1]
}
}
for i := 0; i < n-1; i++ {
if leftMax[i] <= rightMin[i+1] {
return i+1
}
}
return n
}
Java
class Solution {
public int partitionDisjoint(int[] nums) {
int n = nums.length;
int[] leftMax = new int[n], rightMin = new int[n];
leftMax[0] = nums[0];
for (int i = 1; i < n; i++)
leftMax[i] = Math.max(leftMax[i-1], nums[i]);
rightMin[n-1] = nums[n-1];
for (int i = n-2; i >= 0; i--)
rightMin[i] = Math.min(rightMin[i+1], nums[i]);
for (int i = 0; i < n-1; i++) {
if (leftMax[i] <= rightMin[i+1])
return i+1;
}
return n;
}
}
Kotlin
class Solution {
fun partitionDisjoint(nums: IntArray): Int {
val n = nums.size
val leftMax = IntArray(n)
val rightMin = IntArray(n)
leftMax[0] = nums[0]
for (i in 1 until n) leftMax[i] = maxOf(leftMax[i-1], nums[i])
rightMin[n-1] = nums[n-1]
for (i in n-2 downTo 0) rightMin[i] = minOf(rightMin[i+1], nums[i])
for (i in 0 until n-1) {
if (leftMax[i] <= rightMin[i+1]) return i+1
}
return n
}
}
Python
class Solution:
def partitionDisjoint(self, nums: list[int]) -> int:
n = len(nums)
left_max = [0] * n
right_min = [0] * n
left_max[0] = nums[0]
for i in range(1, n):
left_max[i] = max(left_max[i-1], nums[i])
right_min[-1] = nums[-1]
for i in range(n-2, -1, -1):
right_min[i] = min(right_min[i+1], nums[i])
for i in range(n-1):
if left_max[i] <= right_min[i+1]:
return i+1
return n
Rust
impl Solution {
pub fn partition_disjoint(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut left_max = vec![0; n];
let mut right_min = vec![0; n];
left_max[0] = nums[0];
for i in 1..n {
left_max[i] = left_max[i-1].max(nums[i]);
}
right_min[n-1] = nums[n-1];
for i in (0..n-1).rev() {
right_min[i] = right_min[i+1].min(nums[i]);
}
for i in 0..n-1 {
if left_max[i] <= right_min[i+1] {
return (i+1) as i32;
}
}
n as i32
}
}
TypeScript
class Solution {
partitionDisjoint(nums: number[]): number {
const n = nums.length;
const leftMax = Array(n).fill(0);
const rightMin = Array(n).fill(0);
leftMax[0] = nums[0];
for (let i = 1; i < n; i++)
leftMax[i] = Math.max(leftMax[i-1], nums[i]);
rightMin[n-1] = nums[n-1];
for (let i = n-2; i >= 0; i--)
rightMin[i] = Math.min(rightMin[i+1], nums[i]);
for (let i = 0; i < n-1; i++) {
if (leftMax[i] <= rightMin[i+1])
return i+1;
}
return n;
}
}
Complexity
- ⏰ Time complexity:
O(n), where n is the length of nums. We scan the array three times (for left max, right min, and the answer). - 🧺 Space complexity:
O(n), for the two auxiliary arrays left_max and right_min.