diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md index a7ccb011dbbec..dea13dc8508c7 100644 --- a/solution/2900-2999/2965.Find Missing and Repeated Values/README.md +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md @@ -46,6 +46,14 @@ +**方法一:计数** + +我们创建一个长度为 $n^2 + 1$ 的数组 $cnt$,统计矩阵中每个数字出现的次数。 + +接下来遍历 $i \in [1, n^2]$,如果 $cnt[i] = 2$,则 $i$ 是重复的数字,我们将答案的第一个元素设为 $i$;如果 $cnt[i] = 0$,则 $i$ 是缺失的数字,我们将答案的第二个元素设为 $i$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是矩阵的边长。 + ### **Python3** @@ -53,7 +61,20 @@ ```python - +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans ``` ### **Java** @@ -61,19 +82,99 @@ ```java - +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; ``` ### **Go** ```go +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} +``` +### **TypeScript** + +```ts +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} ``` ### **...** diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md index add969d22e787..ca7c4b95844ba 100644 --- a/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md @@ -38,30 +38,131 @@ ## Solutions +**Solution 1: Counting** + +We create an array $cnt$ of length $n^2 + 1$ to count the frequency of each number in the matrix. + +Next, we traverse $i \in [1, n^2]$. If $cnt[i] = 2$, then $i$ is the duplicated number, and we set the first element of the answer to $i$. If $cnt[i] = 0$, then $i$ is the missing number, and we set the second element of the answer to $i$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the side length of the matrix. + ### **Python3** ```python - +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans ``` ### **Java** ```java - +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; ``` ### **Go** ```go +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} +``` +### **TypeScript** + +```ts +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} ``` ### **...** diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp new file mode 100644 index 0000000000000..a94e3d15225cc --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go new file mode 100644 index 0000000000000..841abb696fdd2 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go @@ -0,0 +1,19 @@ +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java new file mode 100644 index 0000000000000..6e16f6e31d662 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java @@ -0,0 +1,20 @@ +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py new file mode 100644 index 0000000000000..71e02fe1cf02f --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py @@ -0,0 +1,14 @@ +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts new file mode 100644 index 0000000000000..8603d081c0d10 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts @@ -0,0 +1,18 @@ +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md index 1c8248e8dcf22..de3dab0415aab 100644 --- a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md @@ -53,6 +53,12 @@ +**方法一:排序** + +我们先对数组进行排序,然后每次取出三个元素,如果这三个元素的最大值和最小值的差大于 $k$,则无法满足条件,返回空数组。否则,我们将这三个元素组成的数组加入答案数组中。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -60,7 +66,17 @@ ```python - +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans ``` ### **Java** @@ -68,19 +84,76 @@ ```java - +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; ``` ### **Go** ```go +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} +``` +### **TypeScript** + +```ts +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md index 8c6739fb26aaf..bdd693f15c105 100644 --- a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md @@ -47,30 +47,103 @@ Note that the order of elements is not important. ## Solutions +**Solution 1: Sorting** + +First, we sort the array. Then, we take out three elements each time. If the difference between the maximum and minimum values of these three elements is greater than $k$, then the condition cannot be satisfied, and we return an empty array. Otherwise, we add the array composed of these three elements to the answer array. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** ```python - +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans ``` ### **Java** ```java - +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; ``` ### **Go** ```go +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} +``` +### **TypeScript** + +```ts +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp new file mode 100644 index 0000000000000..9eba2fe563175 --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp @@ -0,0 +1,16 @@ +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go new file mode 100644 index 0000000000000..d9ab6189f21bf --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go @@ -0,0 +1,12 @@ +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java new file mode 100644 index 0000000000000..0497818388191 --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java @@ -0,0 +1,15 @@ +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py new file mode 100644 index 0000000000000..9b1bd2b3f8c1e --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py @@ -0,0 +1,11 @@ +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts new file mode 100644 index 0000000000000..3e2841c973c2c --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts @@ -0,0 +1,12 @@ +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md index ccb8f0392b6cb..2da90d5ae24be 100644 --- a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md @@ -57,6 +57,36 @@ +**方法一:排序 + 前缀和 + 二分查找** + +题目求的是在最多进行 $k$ 次操作的情况下,我们能得到的众数的最大频率。如果我们将数组 $nums$ 按照从小到大的顺序排列,那么最好就是将一段连续的数字都变成同一个数,这样可以使得操作次数较少,并且众数的频率较高。 + +因此,我们不妨先对数组 $nums$ 进行排序。 + +接下来,我们再分析,如果一个频率 $x$ 是可行的,那么对于任意 $y \le x$,频率 $y$ 也是可行的,这存在着单调性。因此,我们可以通过二分查找,找到最大的满足条件的频率。 + +我们二分枚举频率,定义二分查找的左边界 $l = 0$,右边界 $r = n$,其中 $n$ 是数组的长度。每次二分查找的过程中,我们取中间值 $mid = \lfloor \frac{l + r + 1}{2} \rfloor$,然后判断 $nums$ 中是否存在一个长度为 $mid$ 的连续子数组,使得这个子数组中的所有元素都变成这个子数组的中位数,且操作次数不超过 $k$。如果存在,那么我们就将左边界 $l$ 更新为 $mid$,否则我们就将右边界 $r$ 更新为 $mid - 1$。 + +为了判断是否存在这样的子数组,我们可以使用前缀和。我们首先定义两个指针 $i$ 和 $j$,初始时 $i = 0$, $j = i + mid$。那么 $nums[i]$ 到 $nums[j - 1]$ 这一段的元素都变成 $nums[(i + j) / 2]$,所需要的操作次数为 $left + right$,其中: + +$$ +\begin{aligned} +\text{left} &= \sum_{k = i}^{(i + j) / 2 - 1} (nums[(i + j) / 2] - nums[k]) \\ +&= ((i + j) / 2 - i) \times nums[(i + j) / 2] - \sum_{k = i}^{(i + j) / 2 - 1} nums[k] +\end{aligned} +$$ + +$$ +\begin{aligned} +\text{right} &= \sum_{k = (i + j) / 2 + 1}^{j} (nums[k] - nums[(i + j) / 2]) \\ +&= \sum_{k = (i + j) / 2 + 1}^{j} nums[k] - (j - (i + j) / 2) \times nums[(i + j) / 2] +\end{aligned} +$$ + +我们可以通过前缀和数组 $s$ 来计算 $\sum_{k = i}^{j} nums[k]$,从而在 $O(1)$ 的时间内计算出 $left$ 和 $right$。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -64,7 +94,28 @@ ```python - +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l ``` ### **Java** @@ -72,19 +123,158 @@ ```java - +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; ``` ### **Go** ```go +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} +``` +### **TypeScript** + +```ts +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +} ``` ### **...** diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md index 5af4970451bd1..8bd11dd5a708b 100644 --- a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md @@ -51,30 +51,220 @@ It can be shown that we cannot achieve a better score. ## Solutions +**Solution 1: Sorting + Prefix Sum + Binary Search** + +The problem asks for the maximum frequency of the mode we can get after performing at most $k$ operations. If we sort the array $nums$ in ascending order, it would be best to turn a continuous segment of numbers into the same number, which can reduce the number of operations and increase the frequency of the mode. + +Therefore, we might as well sort the array $nums$ first. + +Next, we analyze that if a frequency $x$ is feasible, then for any $y \le x$, the frequency $y$ is also feasible, which shows monotonicity. Therefore, we can use binary search to find the maximum feasible frequency. + +We binary search the frequency, define the left boundary of the binary search as $l = 0$, and the right boundary as $r = n$, where $n$ is the length of the array. In each binary search process, we take the middle value $mid = \lfloor \frac{l + r + 1}{2} \rfloor$, and then determine whether there exists a continuous subarray of length $mid$ in $nums$, such that all elements in this subarray become the median of this subarray, and the number of operations does not exceed $k$. If it exists, then we update the left boundary $l$ to $mid$, otherwise we update the right boundary $r$ to $mid - 1$. + +To determine whether such a subarray exists, we can use prefix sum. We first define two pointers $i$ and $j$, initially $i = 0$, $j = i + mid$. Then all elements from $nums[i]$ to $nums[j - 1]$ are changed to $nums[(i + j) / 2]$, and the number of operations required is $left + right$, where: + +$$ +\begin{aligned} +\text{left} &= \sum_{k = i}^{(i + j) / 2 - 1} (nums[(i + j) / 2] - nums[k]) \\ +&= ((i + j) / 2 - i) \times nums[(i + j) / 2] - \sum_{k = i}^{(i + j) / 2 - 1} nums[k] +\end{aligned} +$$ + +$$ +\begin{aligned} +\text{right} &= \sum_{k = (i + j) / 2 + 1}^{j} (nums[k] - nums[(i + j) / 2]) \\ +&= \sum_{k = (i + j) / 2 + 1}^{j} nums[k] - (j - (i + j) / 2) \times nums[(i + j) / 2] +\end{aligned} +$$ + +We can use the prefix sum array $s$ to calculate $\sum_{k = i}^{j} nums[k]$, so as to calculate $left$ and $right$ in $O(1)$ time. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** ```python - +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l ``` ### **Java** ```java - +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; ``` ### **Go** ```go +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} +``` +### **TypeScript** + +```ts +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +} ``` ### **...** diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp new file mode 100644 index 0000000000000..4f8653ba8856a --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go new file mode 100644 index 0000000000000..1a54371c31360 --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go @@ -0,0 +1,34 @@ +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java new file mode 100644 index 0000000000000..4419fce9c5fbb --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java @@ -0,0 +1,34 @@ +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py new file mode 100644 index 0000000000000..5ac1360566fcc --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py @@ -0,0 +1,22 @@ +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts new file mode 100644 index 0000000000000..f3e49ea231c4d --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts @@ -0,0 +1,32 @@ +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +}