# Code language: Python classSolution: defmaxChunksToSorted(self, arr: List[int]) -> int: n = len(arr) val_max, val_min = [a for a in arr], [a for a in arr] for i inrange(1, n): val_max[i] = max(val_max[i - 1], arr[i]) for i inrange(n - 2, -1, -1): val_min[i] = min(val_min[i + 1], arr[i]) returnsum(val_max[i] < val_min[i + 1] for i inrange(n - 1)) + 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Code language: Java classSolution { publicintmaxChunksToSorted(int[] arr) { intn= arr.length, val_max = -1, ans = 0; int[] val_min = arr.clone(); for (inti= n - 2; i >= 0; --i) { val_min[i] = Math.min(val_min[i + 1], arr[i]); } for (inti=1; i < n; ++i) { val_max = Math.max(val_max, arr[i - 1]); if (val_max < val_min[i]) ++ans; } return ans + 1; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Code language: C++ classSolution { public: intmaxChunksToSorted(vector<int>& arr){ int n = arr.size(), val_max = -1, ans = 0; int val_min[17]; val_min[n - 1] = arr[n - 1]; for (int i = n - 2; i >= 0; --i) { val_min[i] = min(val_min[i + 1], arr[i]); } for (int i = 1; i < n; ++i) { val_max = max(val_max, arr[i - 1]); if (val_max < val_min[i]) ++ans; } return ans + 1; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* Code language: JavaScript */ /** * @param {number[]} arr * @return {number} */ var maxChunksToSorted = function(arr) { const n = arr.length; const val_min = newArray(n).fill(0); val_min[n - 1] = arr[n - 1]; for (let i = n - 2; i >= 0; --i) { val_min[i] = Math.min(val_min[i + 1], arr[i]); } let ans = 0, val_max = -1; for (let i = 1; i < n; ++i) { val_max = Math.max(val_max, arr[i - 1]); if (val_max < val_min[i]) ++ans; } return ans + 1; };
/* Code language: Go */ funcmaxChunksToSorted(arr []int)int { n := len(arr) val_min := make([]int, n) val_min[n - 1] = arr[n - 1] for i:= n - 2; i >= 0; i-- { if val_min[i + 1] < arr[i] { val_min[i] = val_min[i + 1] } else { val_min[i] = arr[i] } } ans, val_max := 0, -1 for i := 1; i < n; i++ { if val_max < arr[i - 1] { val_max = arr[i - 1] } if val_max < val_min[i] { ans++ } } return ans + 1 }
时间复杂度: O(n)
空间复杂度: O(n)
贪心
注意到题目其实给出了数组是 [0, n − 1]
的一个排列,那么我们其实是可以无需预处理的数组就能得知分割点前后的最大最小值的大小关系
假设我们已知某个分割点将数组划分为 [0, i], [i + 1, n − 1],
并且 [0, i] 的最大值为 x
若 x > i,
那么由反证法容易推出 $\exist y \in arr[i + 1,
n - 1]$, 使得 y < x, 即此时的 i 不能作为分割点
若 x = = i,
那么不难发现 [0, i]
内的数值就是 [0, i]
的一个排列,而 [i + 1, n − 1]
不可能出现小于 i
的值了,所以此时的 i
是一个有效的分割点
若 x < i,
那么LeetCode 会告诉你这个测试用例不符合要求…
据此可以省略掉预处理数组的步骤,只需在遍历同时记录遍历过的部分数组的最大值是否与对应下标相同即可
1 2 3 4
# Code language: Python classSolution: defmaxChunksToSorted(self, arr: List[int]) -> int: returnsum(i == j for i, j inenumerate(accumulate(arr, max)))
1 2 3 4 5 6 7 8 9 10 11
// Code language: Java classSolution { publicintmaxChunksToSorted(int[] arr) { intn= arr.length, val_max = -1, ans = 0; for (inti=0; i < n; ++i) { val_max = Math.max(val_max, arr[i]); if (val_max == i) ++ans; } return ans; } }
1 2 3 4 5 6 7 8 9 10 11 12
// Code language: C++ classSolution { public: intmaxChunksToSorted(vector<int>& arr){ int n = arr.size(), val_max = -1, ans = 0; for (int i = 0; i < n; ++i) { val_max = max(val_max, arr[i]); if (val_max == i) ++ans; } return ans; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* Code language: JavaScript */ /** * @param {number[]} arr * @return {number} */ var maxChunksToSorted = function(arr) { const n = arr.length; let val_max = -1, ans = 0; for (let i = 0; i < n; ++i) { val_max = Math.max(val_max, arr[i]); if (val_max == i) ++ans; } return ans; };
1 2 3 4 5 6 7 8 9 10 11 12 13
/* Code language: Go */ funcmaxChunksToSorted(arr []int)int { val_max, ans := -1, 0 for i, j := range arr { if val_max < j { val_max = j } if val_max == i { ans++ } } return ans }