problemmediumalgorithmsleetcode-915leetcode 915leetcode915

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 left is less than or equal to every element in right.
  • left and right are non-empty.
  • left has 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^5
  • 0 <= 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

  1. Compute an array left_max where left_max[i] is the maximum of nums[0..i].
  2. Compute an array right_min where right_min[i] is the minimum of nums[i..n-1].
  3. Find the smallest index i where left_max[i] <= right_min[i+1].
  4. Return i+1 as the length of left.

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.

Comments