classSolution { public: intmaximumElementAfterDecrementingAndRearranging(vector<int> &arr){ int n = arr.size(); vector<int> cnt(n + 1); for (int v : arr) { ++cnt[min(v, n)]; } int miss = 0; for (int i = 1; i <= n; ++i) { if (cnt[i] == 0) { ++miss; } else { miss -= min(cnt[i] - 1, miss); // miss 不会小于 0,故至多减去 miss 个元素 } } return n - miss; } };
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution { publicintmaximumElementAfterDecrementingAndRearranging(int[] arr) { intn= arr.length; int[] cnt = newint[n + 1]; for (int v : arr) { ++cnt[Math.min(v, n)]; } intmiss=0; for (inti=1; i <= n; ++i) { if (cnt[i] == 0) { ++miss; } else { miss -= Math.min(cnt[i] - 1, miss); // miss 不会小于 0,故至多减去 miss 个元素 } } return n - miss; } }
[sol2-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicclassSolution { publicintMaximumElementAfterDecrementingAndRearranging(int[] arr) { int n = arr.Length; int[] cnt = newint[n + 1]; foreach (int v in arr) { ++cnt[Math.Min(v, n)]; } int miss = 0; for (int i = 1; i <= n; ++i) { if (cnt[i] == 0) { ++miss; } else { miss -= Math.Min(cnt[i] - 1, miss); // miss 不会小于 0,故至多减去 miss 个元素 } } return n - miss; } }
funcmaximumElementAfterDecrementingAndRearranging(arr []int)int { n := len(arr) cnt := make([]int, n+1) for _, v := range arr { cnt[min(v, n)]++ } miss := 0 for _, c := range cnt[1:] { if c == 0 { miss++ } else { miss -= min(c-1, miss) // miss 不会小于 0,故至多减去 miss 个元素 } } return n - miss }
funcmin(a, b int)int { if a < b { return a } return b }
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
var maximumElementAfterDecrementingAndRearranging = function(arr) { const n = arr.length; const cnt = newArray(n + 1).fill(0); for (const v of arr) { ++cnt[Math.min(v, n)]; } let miss = 0; for (let i = 1; i <= n; ++i) { if (cnt[i] == 0) { ++miss; } else { miss -= Math.min(cnt[i] - 1, miss); // miss 不会小于 0,故至多减去 miss 个元素 } } return n - miss; };
[sol2-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
intmaximumElementAfterDecrementingAndRearranging(int *arr, int arrSize) { int cnt[arrSize + 1]; memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < arrSize; i++) { cnt[(int)fmin(arr[i], arrSize)]++; } int miss = 0; for (int i = 1; i <= arrSize; ++i) { if (cnt[i] == 0) { ++miss; } else { miss -= fmin(cnt[i] - 1, miss); // miss 不会小于 0,故至多减去 miss 个元素 } } return arrSize - miss; }
复杂度分析
时间复杂度:O(n),其中 n 是数组 arr 的长度。我们仅需遍历 arr 数组和 cnt 数组各一次,因此时间复杂度为 O(n)。