Partition Array into Disjoint Intervals

Updated on 30 June, 2025
Partition Array into Disjoint Intervals header image

Problem Statement

The task is to perform a specific partition on an integer array nums into two contiguous subarrays, left and right. The partitioning must be done such that every member of left is less than or equal to each member of right, each subarray must contain at least one element, and left should be as small as possible in terms of length. The outcome needed is the size of the subarray left after making the optimal partition.

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 <= 105
  • 0 <= nums[i] <= 106
  • There is at least one valid answer for the given input.

Approach and Intuition

The essence of this problem revolves around determining a point in the array where every element to the left does not exceed any element to the right. This requires both a keen understanding of array traversal and decision-making based on the properties encountered during this traversal. Let's break down the approach:

  1. Traverse the array from right to left, calculating the minimum value (min_right[i]) from index i to n-1 (where n is the length of the array). This helps in identifying the smallest possible value to the right for each element.

  2. Similarly, traverse the array from left to right to compute the maximum value (max_left[i]) for all elements from the start of the array to index i.

  3. The partition point lies where max_left[i] is less than or equal to min_right[i+1] since this would be the smallest index which ensures all elements in left are necessarily less than or equal to elements in right.

  4. Upon finding such a point, the size of left can simply be i + 1 because this ensures left includes elements from index 0 to i.

By following this strategy, one can determine the minimal size for left which satisfies the condition of each element in left being less than or equal to every element in right. This approach efficiently calculates the necessary partitioning point by leveraging the minima and maxima of subarrays—a classical example of using array preprocessing to simplify a complicated conditional partition problem.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int findPartition(vector<int>& values) {
        int currentMaximum = values[0];
        int maxSoFar = values[0];
        int partitionIndex = 1;
            
        for (int idx = 1; idx < values.size(); ++idx) {
            if (values[idx] < currentMaximum) {
                partitionIndex = idx + 1;
                currentMaximum = maxSoFar;
            } else {
                maxSoFar = max(maxSoFar, values[idx]);
            }
        }
            
        return partitionIndex;
    }
};

The solution provided defines a function to determine an optimal partition point for an array such that the maximum element on the left side is less than or equal to any element on the right side. Here's a breakdown of the approach implemented in C++:

  • Start by initializing currentMaximum and maxSoFar with the first element of the array. These variables help track the largest values while iterating through the array.
  • Initialize partitionIndex to 1, assuming at least the first element forms the left partition initially.
  • Iterate through the array starting from the second element. For each element:
    • If the current element is less than currentMaximum, update partitionIndex to the current position plus one, and set currentMaximum to maxSoFar. This step adjusts the partition point whenever a smaller element that violates the condition is found.
    • If the current element is greater than or equal to currentMaximum, update maxSoFar to the maximum of maxSoFar and the current element to keep tracking the maximum value observed so far.

At the end of the iteration, the function returns partitionIndex, which indicates the position where the array should be divided into two disjoint intervals. This partition point ensures all elements to the left are smaller or equal to any element on the right.

This logic ensures an efficient solution with a time complexity of O(n), where n is the number of elements in the array, since it processes each element in a single pass.

java
class Solution {
    public int findPartitionPoint(int[] array) {
        int maxInLeft = array[0];
        int overallMax = array[0];
        int partitionIdx = 1;
            
        for (int j = 1; j < array.length; ++j) {
            if (array[j] < maxInLeft) {
                partitionIdx = j + 1;
                maxInLeft = overallMax;
            } else {
                overallMax = Math.max(overallMax, array[j]);
            }
        }
            
        return partitionIdx;
    }
}

This Java solution resolves the problem of finding a partition index in an array such that all elements to the left of the index are less than or equal to all elements to the right of the index. Implement this functionality using the findPartitionPoint method within the Solution class.

  • Initialize two integers, maxInLeft and overallMax, to the first element of the array. This establishes the basis for comparing subsequent elements.
  • Initialize partitionIdx to 1, assuming the smallest possible partition after the first element.
  • Traverse the array starting from the second element:
    1. If the current element is less than maxInLeft, update partitionIdx to the current position plus one. Also, update maxInLeft to overallMax because the current element dictates a new partition point.
    2. If the current element is not less than maxInLeft, update overallMax to the maximum of overallMax and the current element to continually track the highest value seen so far.
  • Return partitionIdx, which gives the position where the array can be partitioned according to the specified condition.

Ensure to test this solution with various scenarios to confirm it accurately identifies the partition point, considering both initial, all-equal elements, and mixed-value arrays.

python
class Solution:
    def findPartition(self, arr: List[int]) -> int:
        left_max = arr[0]
        max_so_far = arr[0]
        partition_index = 1
            
        for j in range(1, len(arr)):
            if arr[j] < left_max:
                partition_index = j + 1
                left_max = max_so_far
            else:
                max_so_far = max(max_so_far, arr[j])
                    
        return partition_index

The problem involves partitioning an array into two disjoint intervals such that every element in the left interval is less than or equal to every element in the right interval. The goal is to find the minimum size of the left interval that satisfies this condition.

The provided Python solution utilizes a single pass through the array while maintaining two key variables: left_max and max_so_far. left_max keeps track of the maximum value in the left interval, and max_so_far records the maximum value encountered so far as the array is traversed. The algorithm progresses as follows:

  1. Initialize left_max and max_so_far to the first element of the array.
  2. Initialize partition_index to 1, indicating the starting smallest possible size of the left interval.
  3. Loop through the array starting from the second element.
    • If the current element is less than left_max, it necessitates extending the left interval to include this element. Update partition_index to the current position plus one and also set left_max to max_so_far to reflect the new left interval's maximum.
    • If the current element is greater than or equal to left_max, simply update max_so_far to reflect the new maximum value encountered.
  4. Return partition_index, which now points to the first element of the right interval, marking the end of the left interval plus one.

This approach ensures an optimal and efficient solution with only a single iteration through the array and constant space complexity, making it well-suited for large inputs.

Comments

No comments yet.