leetcode.数组.769最多能完成排序的块-Java
1. 具体题目
数组arr是[0, 1, ..., arr.length - 1]的一种排列,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。我们最多能将数组分成多少块?
示例 1: 输入: arr = [4,3,2,1,0] 输出: 1 解释: 将数组分成2块或者更多块,都无法得到所需的结果。例如,分成 [4, 3], [2, 1, 0] 的结果是 [3, 4, 0, 1, 2],这不是有序的数组。
2. 思路分析
对本题来说,如果数组有序,每个元素的值应该与其索引相同。对于索引 i, 如果在它之前的元素值有大于 i 的,那么将 i 之前的元素分为一块,排序后大于 i 的值无法处理。所以,索引 i 之前的元素值要都小于 i 才能分为一块。遍历数组,将索引 i 之前的元素值存到一个 list 中,如果 list 中的值都小于 i,那么可以分为一块。为了减少每次比较的次数,如果当前 list 中的数满足要求,块数 + 1 的同时清空当前 list。
3. 代码
1 public int maxChunksToSorted(int[] arr) { 2 ArrayList<Integer> front = new ArrayList<>(); 3 int count = 0; 4 for(int i = 0; i < arr.length; i++){ 5 front.add(arr[i]); 6 boolean flag = true; 7 for(int num : front){ 8 if(num > i){ 9 flag = false; 10 } 11 } 12 if(flag){ 13 count++; 14 front.clear(); 15 } 16 } 17 return count; 18 }
4. 思路优化
不用比较索引 i 之前所有元素的值,而是每次更新当前最大值,用此最大值与 i 比较即可。
5. 代码优化
1 public int maxChunksToSorted(int[] arr) { 2 int max = 0, count = 0; 3 for(int i = 0; i < arr.length; i++){ 4 max = Math.max(max, arr[i]); 5 if(max <= i) count++; 6 } 7 return count; 8 }

浙公网安备 33010602011771号