This question is the same as “Max Chunks to Make Sorted” except the integers of the given array are not necessarily distinct, the input array could be up to length 2000, and the elements could be up to 10**8.
Given an array arr of integers (not necessarily distinct), we split the array into some number of “chunks” (partitions), and individually sort each chunk. After concatenating them, the result equals the sorted array.
What is the most number of chunks we could have made?
Example 1:
Input: arr = [5,4,3,2,1]
Output: 1
Explanation:
Splitting into two or more chunks will not return the required result.
For example, splitting into [5, 4], [3, 2, 1] will result in [4, 5, 1, 2, 3], which isn’t sorted.
Example 2:
Input: arr = [2,1,3,4,4]
Output: 4
Explanation:
We can split into two chunks, such as [2, 1], [3, 4, 4].
However, splitting into [2, 1], [3], [4], [4] is the highest number of chunks possible.
Note:
arr will have length in range [1, 2000].
arr[i] will be an integer in range [0, 10**8].
和769.可排序最大块数类似,分块局部排序,拼在一起后整体要是升序的。不同之处在于数字可以有相同的。
思路:
769题采用下标来判断某数字之前的数字是否全出现过,因为有相同的数字所以不能再用此方法。
方法1: 局部和
能单独分块的部分元素的和 == 排序后相同部分的元素和
出现元素和相等的部分时块数++
保存和时用long型
//1ms
public int maxChunksToSorted(int[] arr) {
int n = arr.length;
int[] sorted = arr.clone();
Arrays.sort(arr);
long sum1 = 0;
long sum2 = 0;
int result = 0;
for(int i = 0; i < n; i++) {
sum1 += arr[i];
sum2 += sorted[i];
if(sum1 == sum2) {
result ++;
}
}
return result;
}
方法2:单调stack
和769题思路类似,能分块的部分要保证<=当前元素的值都已经出现过。>当前元素的值来时说明块数可+1,<=当前元素的值来时要找到之前比它大的值作为一块。
按照这个思路,>当前元素的值来时压入stack保存,<=当前元素的值来时从stack取出元素直到找到比它大的值,把这个比它大的值压入stack作为某块的结尾。
最后只要看stack中有几个元素,就代表存了几块的结尾。
//3ms
public int maxChunksToSorted(int[] arr) {
int n = arr.length;
Stack<Integer> stack = new Stack<>();
stack.push(arr[0]);
int maxNum = 0;
for(int i = 1; i < n; i++) {
if(arr[i] >= stack.peek()) {
stack.push(arr[i]);
} else {
maxNum = stack.pop();
while(!stack.empty() && stack.peek() > arr[i]) {
stack.pop();
}
stack.push(maxNum);
}
}
return stack.size();
}