Given an array arr
that is a permutation of [0, 1, ..., arr.length - 1]
, 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 = [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.
Example 2:
Input: arr = [1,0,2,3,4] Output: 4 Explanation: We can split into two chunks, such as [1, 0], [2, 3, 4]. However, splitting into [1, 0], [2], [3], [4] is the highest number of chunks possible.
Note:
arr
will have length in range[1, 10]
.arr[i]
will be a permutation of[0, 1, ..., arr.length - 1]
.
题意:
给0~arr.length-1的一个排列,我们将数组拆分成一些“块”(分区),并对每个块进行单独排序。 连接它们之后,结果等于排序后的数组。问最多能够分成多少个分区(块)
分析:
例子:arr = [1,0,2,3,4]
在这个例子中,一种方法是将arr分为两个chunks,[1,0]和[2,3,4]。这样如果我们对两个chunks分别排序然后再和到一起,整个数组就是排好序的了。(参照下图解释)
但是,这种分发不是题目所要的最多chunks的分发,最多的分发是可以把原数组分为4个chunks。(参照下图)
下面我们就来分析如何找到这种最多的分法。
首先,什么样的chunk是合理的呢?因为我们不能调换chunk和chunk之间的顺序,所以就像quicksort的partition一样,每个chunk中的数字必须比它之前chunk中的所有数字都打并且比它之后的chunk中的所有数字都小。
所以,下图中给出的2种分发,第一个是合理的(每一个chunk里面的数都比前面的chunk大都比后面的chunk小),而第二种分发是不合理的,因为第二个chunk中包含0,这个0小于第一个chunk中的1。
如果分析出了这第一点,那题目的思路就清楚了。我们只要维护一个数组max[],max[i]表示输入数字arr[0...i]这个区间最大的值。因为这个输入数组包含所有0到n-1的数字,所以我们只需要从左到右来判断是否max[i] == i,如果满足就说明了小于等于i的数都在包含了,这里可以是所谓chunk的一个分割点。
具体实现如下:
public int maxChunksToSorted(int[] arr) {
int len = arr.length;
int[] max = new int[len];
max[0] = arr[0];
for (int i = 1; i < len; i ++) {
if (arr[i] > max[i-1]) {
max[i] = arr[i];
} else {
max[i] = max[i-1];
}
}
int res = 0;
for (int i = 0; i < len; i ++) {
if (max[i] == i) {
res ++;
}
}
return res;
}