Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/915.html

915. Partition Array into Disjoint Intervals

Level

Medium

Description

Given an array A, 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 of left after such a partitioning. It is guaranteed that such a partitioning exists.

Example 1:

Input: [5,0,3,8,6]

Output: 3

Explanation: left = [5,0,3], right = [8,6]

Example 2:

Input: [1,1,1,0,6,12]

Output: 4

Explanation: left = [1,1,1,0], right = [6,12]

Note:

  1. 2 <= A.length <= 30000
  2. 0 <= A[i] <= 10^6
  3. It is guaranteed there is at least one way to partition A as described.

Solution

Create an array minRight that has the same length as A, where minRight[i] represents the minimum element in the subarray A[i..A.length-1]. Then loop over A from left to right and maintain the maximum element met so far, which is maxLeft. Once an index such that maxLeft <= minRight[index + 1] is met, return index + 1. Since it is guaranteed that such a partitioning exists, the maximum possible return value is A.length - 1.

  • class Solution {
        public int partitionDisjoint(int[] A) {
            int length = A.length;
            int[] minRight = new int[length];
            minRight[length - 1] = A[length - 1];
            for (int i = length - 2; i >= 0; i--)
                minRight[i] = Math.min(minRight[i + 1], A[i]);
            int maxLeft = Integer.MIN_VALUE;
            for (int i = 0; i < length - 1; i++) {
                maxLeft = Math.max(maxLeft, A[i]);
                if (maxLeft <= minRight[i + 1])
                    return i + 1;
            }
            return length - 1;
        }
    }
    
  • // OJ: https://leetcode.com/problems/partition-array-into-disjoint-intervals/
    // Time: O(N)
    // Space: O(N)
    class Solution {
    public:
        int partitionDisjoint(vector<int>& A) {
            deque<int> q; // index
            int N = A.size(), mx = 0;
            for (int i = 0; i < N; ++i) {
                while (q.size() && A[q.back()] >= A[i]) q.pop_back();
                q.push_back(i);
            }
            for (int i = 0; i < N; ++i) {
                if (q.front() == i) q.pop_front();
                mx = max(mx, A[i]);
                if (mx <= A[q.front()]) return i + 1;
            }
            return -1;
        }
    };
    
  • class Solution:
        def partitionDisjoint(self, nums: List[int]) -> int:
            n = len(nums)
            mi = [inf] * (n + 1)
            for i in range(n - 1, -1, -1):
                mi[i] = min(nums[i], mi[i + 1])
            mx = 0
            for i, v in enumerate(nums, 1):
                mx = max(mx, v)
                if mx <= mi[i]:
                    return i
    
    ############
    
    class Solution(object):
        def partitionDisjoint(self, A):
            """
            :type A: List[int]
            :rtype: int
            """
            disjoint = 0
            v = A[0]
            max_so_far = v
            for i in range(len(A)):
                max_so_far = max(max_so_far, A[i])
                if A[i] < v:
                    v = max_so_far
                    disjoint = i
            return disjoint + 1
    
  • func partitionDisjoint(nums []int) int {
    	n := len(nums)
    	mi := make([]int, n+1)
    	mi[n] = nums[n-1]
    	for i := n - 1; i >= 0; i-- {
    		mi[i] = min(nums[i], mi[i+1])
    	}
    	mx := 0
    	for i := 1; i <= n; i++ {
    		v := nums[i-1]
    		mx = max(mx, v)
    		if mx <= mi[i] {
    			return i
    		}
    	}
    	return 0
    }
    
    func max(a, b int) int {
    	if a > b {
    		return a
    	}
    	return b
    }
    
    func min(a, b int) int {
    	if a < b {
    		return a
    	}
    	return b
    }
    

All Problems

All Solutions