LeetCode768/769 Maximum Chunks to make sorted1/2
LC769 Max Chunks To Make Sorted
this is kind of odd problem, and I think rephrase this way would be much better to understand.
so we are given an array, it’s sorted or not sorted, we don’t know. now, we want to make it sorted, and we are required to divide this array into several part, so that if we sorted each part, and combined them, then the new array is sorted. now, we want to know the most number of chunks we could have made.
and pay attention: the input array is the permutation of [0,1,2,3,4…arr.length-1]
Example:
Input: arr = [4,3,2,1,0]
Output: 1
Explanation:
Splitting into two or more chunks will not return the required result.
For example, splitting into [4, 3], [2, 1, 0] will result in [3, 4, 0, 1, 2], which isn’t sorted.
Solution1:
since we want the most number chunks, so each chunk need to be as small as possible, so from left to right, we get the maximum number so far, if this number is equals to the current index, then it means that if we split here, and sort everything from previous split point to current value, we can get a sorted array at last.
which can be summerized as: find the earlist valid split point.
class Solution {
public int maxChunksToSorted(int[] arr) {
int res = 0;
int max = Integer.MIN_VALUE;
for (int i = 0; i<arr.length; i++) {
max = Math.max(max, arr[i]);
if (max == i) {
res++;
}
}
return res;
}
}
LC768 Max Chunks To Make Sorted2:
this is the follow up of LC769.
Now, the input array is not [0,1,2…arr.length-1]
instead, it can be anything, and it may includes duplicates. all other rules are the same as LC769. Now, What is the most number of chunks we could have made?
I can’t think of any idea to solve this problem.
and according to leetcode, there is a genius way to solve this problem.
every element can be seen as a potential break point, but not every element can be a valid break point. so what kind of element can be seen as a vaild point? the answer is:
we calculate the max value of (previous elements and current element), let’s call it maxOfLeft[i]
and the min value of (later elements and current element), let’s call it minOfRight[i]
and if maxOfLeft[i] <= minOfRight[i+1], that means, the max of [0, i] is less than the min of [i+1, end], so i is definitly a split point, so res++.
and don’t forget to return res+1.
but I have a problem:
do I need to get maxOfRight and minOfLeft to get valid split point, and check if this split point is found out before or it is a new valid point?
Answer: No, don’t need to and if you do, you get a wrong solution, because if minOfLeft[i] >= maxOfRight[i+1], we can’t see i as the valid split point, why? because we want to sort the original array from small to bigger, instead of (from bigger to smaller), or (just monotonic order).
class Solution {
public int maxChunksToSorted(int[] arr) {
int len = arr.length;
int[] maxOfLeft = new int[len]; //maxOfLeft[i] means the max of [0, i]
int[] minOfRight = new int[len];
maxOfLeft[0] = arr[0];
for (int i = 1; i < len; i++) {
maxOfLeft[i] = Math.max(maxOfLeft[i-1], arr[i]);
}
minOfRight[len - 1] = arr[len - 1];
for (int i = len - 2; i >= 0; i--) {
minOfRight[i] = Math.min(minOfRight[i + 1], arr[i]);
}
int res = 0;
for (int i = 0; i < len - 1; i++) {
if (maxOfLeft[i] <= minOfRight[i+1]) {
res++;
}
}
return res+1;
}
}

浙公网安备 33010602011771号