Leetcode 915. Partition Array into Disjoint Intervals
Problem:
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 inright
. left
andright
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:
2 <= A.length <= 30000
0 <= A[i] <= 10^6
- It is guaranteed there is at least one way to partition
A
as described.
Solution:
不得不说,这是道很有意思的题目,虽然只是medium,但要想出O(n)时间复杂度和O(1)空间复杂度的解法也不容易。这道题要求我们划分数组,使得left数组里的最大值不大于right数组中的最小值。因此我们维护两个变量leftMax和maximal,leftMax是已经确定在左侧数组中的最大值,maximal是当前位置左侧的最大值。这里有几个关键点,什么时候maximal等于leftMax,如果A[i]小于leftMax时,如果A[i]是right数组中的,那么right中的A[i]会小于left数组中的leftMax,因此当A[i]小于leftMax时A[i]必然是left数组的右界限,因此i左侧的maximal此时赋值给leftMax。如果A[i]大于leftMax,我们是无法断定A[i]是属于left还是right的,因此我们只需要更新maximal即可。
Code:
1 class Solution { 2 public: 3 int partitionDisjoint(vector<int>& A) { 4 int result = 0; 5 int leftMax = A[0]; 6 int maximal = A[0]; 7 for(int i = 1;i != A.size();++i){ 8 if(A[i] < leftMax){ 9 result = i; 10 leftMax = maximal; 11 } 12 else{ 13 maximal = max(maximal,A[i]); 14 } 15 } 16 return result+1; 17 } 18 };