diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README.md b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README.md index 3f66d34f912b7..0ecf75fa512ed 100644 --- a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README.md +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README.md @@ -64,6 +64,14 @@ +**方法一:模拟** + +我们遍历区间 $[1, n]$ 中的每一个数,如果它能被 $m$ 整除,那么答案就减去这个数,否则答案就加上这个数。 + +遍历结束后,返回答案即可。 + +时间复杂度 $O(n)$,其中 $n$ 是题目给定的整数。空间复杂度 $O(1)$。 + ### **Python3** @@ -71,7 +79,9 @@ ```python - +class Solution: + def differenceOfSums(self, n: int, m: int) -> int: + return sum(i if i % m else -i for i in range(1, n + 1)) ``` ### **Java** @@ -79,19 +89,57 @@ ```java - +class Solution { + public int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m == 0 ? -i : i; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; + } +}; ``` ### **Go** ```go +func differenceOfSums(n int, m int) (ans int) { + for i := 1; i <= n; i++ { + if i%m == 0 { + ans -= i + } else { + ans += i + } + } + return +} +``` + +### **TypeScript** +```ts +function differenceOfSums(n: number, m: number): number { + let ans = 0; + for (let i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; +} ``` ### **...** diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README_EN.md b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README_EN.md index 7c13e0baee5ba..71aba2f6af45a 100644 --- a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README_EN.md +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/README_EN.md @@ -58,30 +58,78 @@ We return 0 - 15 = -15 as the answer. ## Solutions +**Solution 1: Simulation** + +We traverse every number in the range $[1, n]$. If it is divisible by $m$, we subtract it from the answer. Otherwise, we add it to the answer. + +After the traversal, we return the answer. + +The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$. + ### **Python3** ```python - +class Solution: + def differenceOfSums(self, n: int, m: int) -> int: + return sum(i if i % m else -i for i in range(1, n + 1)) ``` ### **Java** ```java - +class Solution { + public int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m == 0 ? -i : i; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; + } +}; ``` ### **Go** ```go +func differenceOfSums(n int, m int) (ans int) { + for i := 1; i <= n; i++ { + if i%m == 0 { + ans -= i + } else { + ans += i + } + } + return +} +``` + +### **TypeScript** +```ts +function differenceOfSums(n: number, m: number): number { + let ans = 0; + for (let i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; +} ``` ### **...** diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.cpp b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.cpp new file mode 100644 index 0000000000000..c40a823aa3c9f --- /dev/null +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.cpp @@ -0,0 +1,10 @@ +class Solution { +public: + int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.go b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.go new file mode 100644 index 0000000000000..9a960809266a0 --- /dev/null +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.go @@ -0,0 +1,10 @@ +func differenceOfSums(n int, m int) (ans int) { + for i := 1; i <= n; i++ { + if i%m == 0 { + ans -= i + } else { + ans += i + } + } + return +} \ No newline at end of file diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.java b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.java new file mode 100644 index 0000000000000..2641981332d41 --- /dev/null +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.java @@ -0,0 +1,9 @@ +class Solution { + public int differenceOfSums(int n, int m) { + int ans = 0; + for (int i = 1; i <= n; ++i) { + ans += i % m == 0 ? -i : i; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.py b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.py new file mode 100644 index 0000000000000..536dd5344916f --- /dev/null +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.py @@ -0,0 +1,3 @@ +class Solution: + def differenceOfSums(self, n: int, m: int) -> int: + return sum(i if i % m else -i for i in range(1, n + 1)) diff --git a/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.ts b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.ts new file mode 100644 index 0000000000000..7d8d026353501 --- /dev/null +++ b/solution/2800-2899/2894.Divisible and Non-divisible Sums Difference/Solution.ts @@ -0,0 +1,7 @@ +function differenceOfSums(n: number, m: number): number { + let ans = 0; + for (let i = 1; i <= n; ++i) { + ans += i % m ? i : -i; + } + return ans; +} diff --git a/solution/2800-2899/2895.Minimum Processing Time/README.md b/solution/2800-2899/2895.Minimum Processing Time/README.md index 3953037da1424..5fc2a5f36b7dd 100644 --- a/solution/2800-2899/2895.Minimum Processing Time/README.md +++ b/solution/2800-2899/2895.Minimum Processing Time/README.md @@ -53,6 +53,14 @@ +**方法一:贪心 + 排序** + +要使得处理完所有任务的时间最小,那么越早处于空闲状态的处理器应该处理耗时最长的 $4$ 个任务。 + +因此,我们对处理器的空闲时间和任务的耗时分别进行排序,然后依次将耗时最长的 $4$ 个任务分配给空闲时间最早的处理器,计算最大的结束时间即可。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为任务的数量。 + ### **Python3** @@ -60,7 +68,16 @@ ```python - +class Solution: + def minProcessingTime(self, processorTime: List[int], tasks: List[int]) -> int: + processorTime.sort() + tasks.sort() + ans = 0 + i = len(tasks) - 1 + for t in processorTime: + ans = max(ans, t + tasks[i]) + i -= 4 + return ans ``` ### **Java** @@ -68,19 +85,73 @@ ```java - +class Solution { + public int minProcessingTime(List processorTime, List tasks) { + processorTime.sort((a, b) -> a - b); + tasks.sort((a, b) -> a - b); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = Math.max(ans, t + tasks.get(i)); + i -= 4; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int minProcessingTime(vector& processorTime, vector& tasks) { + sort(processorTime.begin(), processorTime.end()); + sort(tasks.begin(), tasks.end()); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = max(ans, t + tasks[i]); + i -= 4; + } + return ans; + } +}; ``` ### **Go** ```go +func minProcessingTime(processorTime []int, tasks []int) (ans int) { + sort.Ints(processorTime) + sort.Ints(tasks) + i := len(tasks) - 1 + for _, t := range processorTime { + ans = max(ans, t+tasks[i]) + i -= 4 + } + return +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` +### **TypeScript** + +```ts +function minProcessingTime(processorTime: number[], tasks: number[]): number { + processorTime.sort((a, b) => a - b); + tasks.sort((a, b) => a - b); + let [ans, i] = [0, tasks.length - 1]; + for (const t of processorTime) { + ans = Math.max(ans, t + tasks[i]); + i -= 4; + } + return ans; +} ``` ### **...** diff --git a/solution/2800-2899/2895.Minimum Processing Time/README_EN.md b/solution/2800-2899/2895.Minimum Processing Time/README_EN.md index bec0c21955f33..9a2b8b6622356 100644 --- a/solution/2800-2899/2895.Minimum Processing Time/README_EN.md +++ b/solution/2800-2899/2895.Minimum Processing Time/README_EN.md @@ -47,30 +47,101 @@ Hence, it can be shown that the minimum time taken to execute all the tasks is 2 ## Solutions +**Solution 1: Greedy + Sorting** + +To minimize the time required to process all tasks, the four tasks with the longest processing time should be assigned to the processors that become idle earliest. + +Therefore, we sort the processors by their idle time and sort the tasks by their processing time. Then, we assign the four tasks with the longest processing time to the processor that becomes idle earliest, and calculate the maximum end time. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the number of tasks. + ### **Python3** ```python - +class Solution: + def minProcessingTime(self, processorTime: List[int], tasks: List[int]) -> int: + processorTime.sort() + tasks.sort() + ans = 0 + i = len(tasks) - 1 + for t in processorTime: + ans = max(ans, t + tasks[i]) + i -= 4 + return ans ``` ### **Java** ```java - +class Solution { + public int minProcessingTime(List processorTime, List tasks) { + processorTime.sort((a, b) -> a - b); + tasks.sort((a, b) -> a - b); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = Math.max(ans, t + tasks.get(i)); + i -= 4; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int minProcessingTime(vector& processorTime, vector& tasks) { + sort(processorTime.begin(), processorTime.end()); + sort(tasks.begin(), tasks.end()); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = max(ans, t + tasks[i]); + i -= 4; + } + return ans; + } +}; ``` ### **Go** ```go +func minProcessingTime(processorTime []int, tasks []int) (ans int) { + sort.Ints(processorTime) + sort.Ints(tasks) + i := len(tasks) - 1 + for _, t := range processorTime { + ans = max(ans, t+tasks[i]) + i -= 4 + } + return +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` +### **TypeScript** + +```ts +function minProcessingTime(processorTime: number[], tasks: number[]): number { + processorTime.sort((a, b) => a - b); + tasks.sort((a, b) => a - b); + let [ans, i] = [0, tasks.length - 1]; + for (const t of processorTime) { + ans = Math.max(ans, t + tasks[i]); + i -= 4; + } + return ans; +} ``` ### **...** diff --git a/solution/2800-2899/2895.Minimum Processing Time/Solution.cpp b/solution/2800-2899/2895.Minimum Processing Time/Solution.cpp new file mode 100644 index 0000000000000..e8a84adde64e6 --- /dev/null +++ b/solution/2800-2899/2895.Minimum Processing Time/Solution.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + int minProcessingTime(vector& processorTime, vector& tasks) { + sort(processorTime.begin(), processorTime.end()); + sort(tasks.begin(), tasks.end()); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = max(ans, t + tasks[i]); + i -= 4; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2895.Minimum Processing Time/Solution.go b/solution/2800-2899/2895.Minimum Processing Time/Solution.go new file mode 100644 index 0000000000000..17eea0fa626f4 --- /dev/null +++ b/solution/2800-2899/2895.Minimum Processing Time/Solution.go @@ -0,0 +1,17 @@ +func minProcessingTime(processorTime []int, tasks []int) (ans int) { + sort.Ints(processorTime) + sort.Ints(tasks) + i := len(tasks) - 1 + for _, t := range processorTime { + ans = max(ans, t+tasks[i]) + i -= 4 + } + return +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/2800-2899/2895.Minimum Processing Time/Solution.java b/solution/2800-2899/2895.Minimum Processing Time/Solution.java new file mode 100644 index 0000000000000..ad573df3d7dc4 --- /dev/null +++ b/solution/2800-2899/2895.Minimum Processing Time/Solution.java @@ -0,0 +1,12 @@ +class Solution { + public int minProcessingTime(List processorTime, List tasks) { + processorTime.sort((a, b) -> a - b); + tasks.sort((a, b) -> a - b); + int ans = 0, i = tasks.size() - 1; + for (int t : processorTime) { + ans = Math.max(ans, t + tasks.get(i)); + i -= 4; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2895.Minimum Processing Time/Solution.py b/solution/2800-2899/2895.Minimum Processing Time/Solution.py new file mode 100644 index 0000000000000..70d00d5f6f81b --- /dev/null +++ b/solution/2800-2899/2895.Minimum Processing Time/Solution.py @@ -0,0 +1,10 @@ +class Solution: + def minProcessingTime(self, processorTime: List[int], tasks: List[int]) -> int: + processorTime.sort() + tasks.sort() + ans = 0 + i = len(tasks) - 1 + for t in processorTime: + ans = max(ans, t + tasks[i]) + i -= 4 + return ans diff --git a/solution/2800-2899/2895.Minimum Processing Time/Solution.ts b/solution/2800-2899/2895.Minimum Processing Time/Solution.ts new file mode 100644 index 0000000000000..b0a621734ef56 --- /dev/null +++ b/solution/2800-2899/2895.Minimum Processing Time/Solution.ts @@ -0,0 +1,10 @@ +function minProcessingTime(processorTime: number[], tasks: number[]): number { + processorTime.sort((a, b) => a - b); + tasks.sort((a, b) => a - b); + let [ans, i] = [0, tasks.length - 1]; + for (const t of processorTime) { + ans = Math.max(ans, t + tasks[i]); + i -= 4; + } + return ans; +} diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README.md b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README.md index 436910d2f9341..36fbc3bcf466b 100644 --- a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README.md +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README.md @@ -55,6 +55,28 @@ +**方法一:记忆化搜索** + +我们注意到,由于每次操作都是反转两个字符,因此,如果不同的字符个数为奇数,那么无法使两个字符串相等,直接返回 $-1$。否则,我们将两个字符串中不同的字符的下标存入数组 $idx$ 中,记数组长度为 $m$。 + +接下来,我们设计一个函数 $dfs(i, j)$,表示将 $idx[i..j]$ 中的字符反转的最小操作代价。答案即为 $dfs(0, m - 1)$。 + +函数 $dfs(i, j)$ 的计算过程如下: + +如果 $i \gt j$,那么不需要进行任何操作,返回 $0$; + +否则,我们考虑对区间 $[i, j]$ 的端点进行操作: + +- 如果我们对端点 $i$ 进行第一种操作,由于代价 $x$ 已经固定,因此,我们最优的选择是将 $idx[i]$ 和 $idx[j]$ 反转,然后递归计算 $dfs(i + 1, j - 1)$,总代价为 $dfs(i + 1, j - 1) + x$; +- 如果我们对端点 $i$ 进行第二种操作,那么我们需要将 $[idx[i]..idx[i + 1]]$ 中的字符全部反转,然后递归计算 $dfs(i + 2, j)$,总代价为 $dfs(i + 2, j) + idx[i + 1] - idx[i]$; +- 如果我们对端点 $j$ 进行第二种操作,那么我们需要将 $[idx[j - 1]..idx[j]]$ 中的字符全部反转,然后递归计算 $dfs(i, j - 2)$,总代价为 $dfs(i, j - 2) + idx[j] - idx[j - 1]$。 + +我们取上述三种操作的最小值,即为 $dfs(i, j)$ 的值。 + +为了避免重复计算,我们可以使用记忆化搜索。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是字符串的长度。 + ### **Python3** @@ -62,7 +84,23 @@ ```python - +class Solution: + def minOperations(self, s1: str, s2: str, x: int) -> int: + @cache + def dfs(i: int, j: int) -> int: + if i > j: + return 0 + a = dfs(i + 1, j - 1) + x + b = dfs(i + 2, j) + idx[i + 1] - idx[i] + c = dfs(i, j - 2) + idx[j] - idx[j - 1] + return min(a, b, c) + + n = len(s1) + idx = [i for i in range(n) if s1[i] != s2[i]] + m = len(idx) + if m & 1: + return -1 + return dfs(0, m - 1) ``` ### **Java** @@ -70,19 +108,155 @@ ```java - +class Solution { + private List idx = new ArrayList<>(); + private Integer[][] f; + private int x; + + public int minOperations(String s1, String s2, int x) { + int n = s1.length(); + for (int i = 0; i < n; ++i) { + if (s1.charAt(i) != s2.charAt(i)) { + idx.add(i); + } + } + int m = idx.size(); + if (m % 2 == 1) { + return -1; + } + this.x = x; + f = new Integer[m][m]; + return dfs(0, m - 1); + } + + private int dfs(int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx.get(i + 1) - idx.get(i)); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx.get(j) - idx.get(j - 1)); + return f[i][j]; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int minOperations(string s1, string s2, int x) { + vector idx; + for (int i = 0; i < s1.size(); ++i) { + if (s1[i] != s2[i]) { + idx.push_back(i); + } + } + int m = idx.size(); + if (m & 1) { + return -1; + } + if (m == 0) { + return 0; + } + int f[m][m]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + f[i][j] = min({dfs(i + 1, j - 1) + x, dfs(i + 2, j) + idx[i + 1] - idx[i], dfs(i, j - 2) + idx[j] - idx[j - 1]}); + return f[i][j]; + }; + return dfs(0, m - 1); + } +}; ``` ### **Go** ```go +func minOperations(s1 string, s2 string, x int) int { + idx := []int{} + for i := range s1 { + if s1[i] != s2[i] { + idx = append(idx, i) + } + } + m := len(idx) + if m&1 == 1 { + return -1 + } + f := make([][]int, m) + for i := range f { + f[i] = make([]int, m) + for j := range f[i] { + f[i][j] = -1 + } + } + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i > j { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + f[i][j] = dfs(i+1, j-1) + x + f[i][j] = min(f[i][j], dfs(i+2, j)+idx[i+1]-idx[i]) + f[i][j] = min(f[i][j], dfs(i, j-2)+idx[j]-idx[j-1]) + return f[i][j] + } + return dfs(0, m-1) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` +### **TypeScript** + +```ts +function minOperations(s1: string, s2: string, x: number): number { + const idx: number[] = []; + for (let i = 0; i < s1.length; ++i) { + if (s1[i] !== s2[i]) { + idx.push(i); + } + } + const m = idx.length; + if (m % 2 === 1) { + return -1; + } + if (m === 0) { + return 0; + } + const f: number[][] = Array.from({ length: m }, () => Array.from({ length: m }, () => -1)); + const dfs = (i: number, j: number): number => { + if (i > j) { + return 0; + } + if (f[i][j] !== -1) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx[i + 1] - idx[i]); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx[j] - idx[j - 1]); + return f[i][j]; + }; + return dfs(0, m - 1); +} ``` ### **...** diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README_EN.md b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README_EN.md index ce36722dcb2b1..f2178e0ae9cc1 100644 --- a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README_EN.md +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/README_EN.md @@ -49,30 +49,204 @@ The total cost is 1 + 1 + 2 = 4. It can be shown that it is the minimum cost pos ## Solutions +**Solution 1: Memoization** + +We notice that since each operation reverses two characters, if the number of different characters in the two strings is odd, it is impossible to make them equal, and we directly return $-1$. Otherwise, we store the indices of the different characters in the two strings in an array $idx$, and let $m$ be the length of $idx$. + +Next, we design a function $dfs(i, j)$, which represents the minimum cost of reversing the characters in $idx[i..j]$. The answer is $dfs(0, m - 1)$. + +The calculation process of the function $dfs(i, j)$ is as follows: + +If $i > j$, we do not need to perform any operation, and return $0$. + +Otherwise, we consider the two endpoints of the interval $[i, j]$: + +- If we perform the first operation on endpoint $i$, since the cost $x$ is fixed, the optimal choice is to reverse $idx[i]$ and $idx[j]$, and then recursively calculate $dfs(i + 1, j - 1)$, with a total cost of $dfs(i + 1, j - 1) + x$. +- If we perform the second operation on endpoint $i$, we need to reverse all the characters in $[idx[i]..idx[i + 1]]$, and then recursively calculate $dfs(i + 2, j)$, with a total cost of $dfs(i + 2, j) + idx[i + 1] - idx[i]$. +- If we perform the second operation on endpoint $j$, we need to reverse all the characters in $[idx[j - 1]..idx[j]]$, and then recursively calculate $dfs(i, j - 2)$, with a total cost of $dfs(i, j - 2) + idx[j] - idx[j - 1]$. + +We take the minimum value of the above three operations as the value of $dfs(i, j)$. + +To avoid redundant calculations, we can use memoization to record the return value of $dfs(i, j)$ in a 2D array $f$. If $f[i][j]$ is not equal to $-1$, it means that we have already calculated it, so we can directly return $f[i][j]$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the strings. + ### **Python3** ```python +class Solution: + def minOperations(self, s1: str, s2: str, x: int) -> int: + @cache + def dfs(i: int, j: int) -> int: + if i > j: + return 0 + a = dfs(i + 1, j - 1) + x + b = dfs(i + 2, j) + idx[i + 1] - idx[i] + c = dfs(i, j - 2) + idx[j] - idx[j - 1] + return min(a, b, c) + n = len(s1) + idx = [i for i in range(n) if s1[i] != s2[i]] + m = len(idx) + if m & 1: + return -1 + return dfs(0, m - 1) ``` ### **Java** ```java +class Solution { + private List idx = new ArrayList<>(); + private Integer[][] f; + private int x; + public int minOperations(String s1, String s2, int x) { + int n = s1.length(); + for (int i = 0; i < n; ++i) { + if (s1.charAt(i) != s2.charAt(i)) { + idx.add(i); + } + } + int m = idx.size(); + if (m % 2 == 1) { + return -1; + } + this.x = x; + f = new Integer[m][m]; + return dfs(0, m - 1); + } + + private int dfs(int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx.get(i + 1) - idx.get(i)); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx.get(j) - idx.get(j - 1)); + return f[i][j]; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int minOperations(string s1, string s2, int x) { + vector idx; + for (int i = 0; i < s1.size(); ++i) { + if (s1[i] != s2[i]) { + idx.push_back(i); + } + } + int m = idx.size(); + if (m & 1) { + return -1; + } + if (m == 0) { + return 0; + } + int f[m][m]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + f[i][j] = min({dfs(i + 1, j - 1) + x, dfs(i + 2, j) + idx[i + 1] - idx[i], dfs(i, j - 2) + idx[j] - idx[j - 1]}); + return f[i][j]; + }; + return dfs(0, m - 1); + } +}; ``` ### **Go** ```go +func minOperations(s1 string, s2 string, x int) int { + idx := []int{} + for i := range s1 { + if s1[i] != s2[i] { + idx = append(idx, i) + } + } + m := len(idx) + if m&1 == 1 { + return -1 + } + f := make([][]int, m) + for i := range f { + f[i] = make([]int, m) + for j := range f[i] { + f[i][j] = -1 + } + } + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i > j { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + f[i][j] = dfs(i+1, j-1) + x + f[i][j] = min(f[i][j], dfs(i+2, j)+idx[i+1]-idx[i]) + f[i][j] = min(f[i][j], dfs(i, j-2)+idx[j]-idx[j-1]) + return f[i][j] + } + return dfs(0, m-1) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + +### **TypeScript** +```ts +function minOperations(s1: string, s2: string, x: number): number { + const idx: number[] = []; + for (let i = 0; i < s1.length; ++i) { + if (s1[i] !== s2[i]) { + idx.push(i); + } + } + const m = idx.length; + if (m % 2 === 1) { + return -1; + } + if (m === 0) { + return 0; + } + const f: number[][] = Array.from({ length: m }, () => Array.from({ length: m }, () => -1)); + const dfs = (i: number, j: number): number => { + if (i > j) { + return 0; + } + if (f[i][j] !== -1) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx[i + 1] - idx[i]); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx[j] - idx[j - 1]); + return f[i][j]; + }; + return dfs(0, m - 1); +} ``` ### **...** diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.cpp b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.cpp new file mode 100644 index 0000000000000..489c4ab6851f8 --- /dev/null +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.cpp @@ -0,0 +1,31 @@ +class Solution { +public: + int minOperations(string s1, string s2, int x) { + vector idx; + for (int i = 0; i < s1.size(); ++i) { + if (s1[i] != s2[i]) { + idx.push_back(i); + } + } + int m = idx.size(); + if (m & 1) { + return -1; + } + if (m == 0) { + return 0; + } + int f[m][m]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + f[i][j] = min({dfs(i + 1, j - 1) + x, dfs(i + 2, j) + idx[i + 1] - idx[i], dfs(i, j - 2) + idx[j] - idx[j - 1]}); + return f[i][j]; + }; + return dfs(0, m - 1); + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.go b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.go new file mode 100644 index 0000000000000..7c728f4feb9b3 --- /dev/null +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.go @@ -0,0 +1,40 @@ +func minOperations(s1 string, s2 string, x int) int { + idx := []int{} + for i := range s1 { + if s1[i] != s2[i] { + idx = append(idx, i) + } + } + m := len(idx) + if m&1 == 1 { + return -1 + } + f := make([][]int, m) + for i := range f { + f[i] = make([]int, m) + for j := range f[i] { + f[i][j] = -1 + } + } + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i > j { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + f[i][j] = dfs(i+1, j-1) + x + f[i][j] = min(f[i][j], dfs(i+2, j)+idx[i+1]-idx[i]) + f[i][j] = min(f[i][j], dfs(i, j-2)+idx[j]-idx[j-1]) + return f[i][j] + } + return dfs(0, m-1) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.java b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.java new file mode 100644 index 0000000000000..44d3986f22eae --- /dev/null +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.java @@ -0,0 +1,34 @@ +class Solution { + private List idx = new ArrayList<>(); + private Integer[][] f; + private int x; + + public int minOperations(String s1, String s2, int x) { + int n = s1.length(); + for (int i = 0; i < n; ++i) { + if (s1.charAt(i) != s2.charAt(i)) { + idx.add(i); + } + } + int m = idx.size(); + if (m % 2 == 1) { + return -1; + } + this.x = x; + f = new Integer[m][m]; + return dfs(0, m - 1); + } + + private int dfs(int i, int j) { + if (i > j) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx.get(i + 1) - idx.get(i)); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx.get(j) - idx.get(j - 1)); + return f[i][j]; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.py b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.py new file mode 100644 index 0000000000000..b5a7c7be4fcdd --- /dev/null +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.py @@ -0,0 +1,17 @@ +class Solution: + def minOperations(self, s1: str, s2: str, x: int) -> int: + @cache + def dfs(i: int, j: int) -> int: + if i > j: + return 0 + a = dfs(i + 1, j - 1) + x + b = dfs(i + 2, j) + idx[i + 1] - idx[i] + c = dfs(i, j - 2) + idx[j] - idx[j - 1] + return min(a, b, c) + + n = len(s1) + idx = [i for i in range(n) if s1[i] != s2[i]] + m = len(idx) + if m & 1: + return -1 + return dfs(0, m - 1) diff --git a/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.ts b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.ts new file mode 100644 index 0000000000000..4df0dc973ce76 --- /dev/null +++ b/solution/2800-2899/2896.Apply Operations to Make Two Strings Equal/Solution.ts @@ -0,0 +1,29 @@ +function minOperations(s1: string, s2: string, x: number): number { + const idx: number[] = []; + for (let i = 0; i < s1.length; ++i) { + if (s1[i] !== s2[i]) { + idx.push(i); + } + } + const m = idx.length; + if (m % 2 === 1) { + return -1; + } + if (m === 0) { + return 0; + } + const f: number[][] = Array.from({ length: m }, () => Array.from({ length: m }, () => -1)); + const dfs = (i: number, j: number): number => { + if (i > j) { + return 0; + } + if (f[i][j] !== -1) { + return f[i][j]; + } + f[i][j] = dfs(i + 1, j - 1) + x; + f[i][j] = Math.min(f[i][j], dfs(i + 2, j) + idx[i + 1] - idx[i]); + f[i][j] = Math.min(f[i][j], dfs(i, j - 2) + idx[j] - idx[j - 1]); + return f[i][j]; + }; + return dfs(0, m - 1); +} diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README.md b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README.md index 895ee9ef0f7dd..f8f31ef892f7a 100644 --- a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README.md +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README.md @@ -57,6 +57,14 @@ +**方法一:位运算 + 贪心** + +根据题目描述,对于一个操作,我们可以将 $nums[i]$ 变为 $nums[i] \text{ AND } nums[j]$,将 $nums[j]$ 变为 $nums[i] \text{ OR } nums[j]$。我们不妨按位考虑,两个 $1$ 或两个 $0$ 进行这样的操作,结果都不会改变,如果是 $1$ 和 $0$ 进行这样的操作,结果会变成 $0$ 和 $1$,也即是说,我们可以将 $1$ 转移到 $0$ 上,而 $0$ 不会转移到 $1$ 上。 + +因此,我们可以用一个数组 $cnt$ 统计每个位置上 $1$ 的个数,然后从中选择 $k$ 个数。由于要使得平方和最大,每次选择的数要尽可能大。这是因为,假设两个数的平方和为 $a^2 + b^2$(其中 $a \gt b$),将两个数平方和变成 $(a + c)^2 + (b - c)^2 = a^2 + b^2 + 2c(a - b) + 2c^2 \gt a^2 + b^2$。因此,为了最大化平方和,我们应该让一个数字尽可能大。 + +时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$,其中 $M$ 是数组中的最大值。 + ### **Python3** @@ -64,7 +72,23 @@ ```python - +class Solution: + def maxSum(self, nums: List[int], k: int) -> int: + mod = 10**9 + 7 + cnt = [0] * 31 + for x in nums: + for i in range(31): + if x >> i & 1: + cnt[i] += 1 + ans = 0 + for _ in range(k): + x = 0 + for i in range(31): + if cnt[i]: + x |= 1 << i + cnt[i] -= 1 + ans = (ans + x * x) % mod + return ans ``` ### **Java** @@ -72,19 +96,117 @@ ```java - +class Solution { + public int maxSum(List nums, int k) { + final int mod = (int) 1e9 + 7; + int[] cnt = new int[31]; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if ((x >> i & 1) == 1) { + ++cnt[i]; + } + } + } + long ans = 0; + while (k-- > 0) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1L * x * x) % mod; + } + return (int) ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxSum(vector& nums, int k) { + int cnt[31]{}; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if (x >> i & 1) { + ++cnt[i]; + } + } + } + long long ans = 0; + const int mod = 1e9 + 7; + while (k--) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i]) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1LL * x * x) % mod; + } + return ans; + } +}; ``` ### **Go** ```go +func maxSum(nums []int, k int) (ans int) { + cnt := [31]int{} + for _, x := range nums { + for i := 0; i < 31; i++ { + if x>>i&1 == 1 { + cnt[i]++ + } + } + } + const mod int = 1e9 + 7 + for ; k > 0; k-- { + x := 0 + for i := 0; i < 31; i++ { + if cnt[i] > 0 { + x |= 1 << i + cnt[i]-- + } + } + ans = (ans + x*x) % mod + } + return +} +``` +### **TypeScript** + +```ts +function maxSum(nums: number[], k: number): number { + const cnt: number[] = Array(31).fill(0); + for (const x of nums) { + for (let i = 0; i < 31; ++i) { + if ((x >> i) & 1) { + ++cnt[i]; + } + } + } + let ans = 0n; + const mod = 1e9 + 7; + while (k-- > 0) { + let x = 0; + for (let i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + BigInt(x) * BigInt(x)) % BigInt(mod); + } + return Number(ans); +} ``` ### **...** diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README_EN.md b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README_EN.md index 590360f0bda48..2b07ae0409758 100644 --- a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README_EN.md +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/README_EN.md @@ -51,30 +51,152 @@ It can be shown that this is the maximum value we can get. ## Solutions +**Solution 1: Bitwise Operation + Greedy** + +According to the problem description, for an operation, we can change $nums[i]$ to $nums[i] \text{ AND } nums[j]$, and change $nums[j]$ to $nums[i] \text{ OR } nums[j]$. Let's consider the bits of the numbers. If two bits are both $1$ or both $0$, the result of the operation will not change the bits. If two bits are different, the result of the operation will change the bits to $0$ and $1$, respectively. Therefore, we can move $1$ bits to $0$ bits, but not vice versa. + +We can use an array $cnt$ to count the number of $1$ bits in each position, and then select $k$ numbers from them. To maximize the sum of squares, we should choose the largest numbers as much as possible. This is because, assuming the sum of squares of two numbers is $a^2 + b^2$ (where $a \gt b$), changing them to $(a + c)^2 + (b - c)^2 = a^2 + b^2 + 2c(a - b) + 2c^2 \gt a^2 + b^2$ will increase the sum of squares. Therefore, to maximize the sum of squares, we should choose the largest number. + +The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log M)$. Here, $M$ is the maximum value in the array. + ### **Python3** ```python - +class Solution: + def maxSum(self, nums: List[int], k: int) -> int: + mod = 10**9 + 7 + cnt = [0] * 31 + for x in nums: + for i in range(31): + if x >> i & 1: + cnt[i] += 1 + ans = 0 + for _ in range(k): + x = 0 + for i in range(31): + if cnt[i]: + x |= 1 << i + cnt[i] -= 1 + ans = (ans + x * x) % mod + return ans ``` ### **Java** ```java - +class Solution { + public int maxSum(List nums, int k) { + final int mod = (int) 1e9 + 7; + int[] cnt = new int[31]; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if ((x >> i & 1) == 1) { + ++cnt[i]; + } + } + } + long ans = 0; + while (k-- > 0) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1L * x * x) % mod; + } + return (int) ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxSum(vector& nums, int k) { + int cnt[31]{}; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if (x >> i & 1) { + ++cnt[i]; + } + } + } + long long ans = 0; + const int mod = 1e9 + 7; + while (k--) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i]) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1LL * x * x) % mod; + } + return ans; + } +}; ``` ### **Go** ```go +func maxSum(nums []int, k int) (ans int) { + cnt := [31]int{} + for _, x := range nums { + for i := 0; i < 31; i++ { + if x>>i&1 == 1 { + cnt[i]++ + } + } + } + const mod int = 1e9 + 7 + for ; k > 0; k-- { + x := 0 + for i := 0; i < 31; i++ { + if cnt[i] > 0 { + x |= 1 << i + cnt[i]-- + } + } + ans = (ans + x*x) % mod + } + return +} +``` +### **TypeScript** + +```ts +function maxSum(nums: number[], k: number): number { + const cnt: number[] = Array(31).fill(0); + for (const x of nums) { + for (let i = 0; i < 31; ++i) { + if ((x >> i) & 1) { + ++cnt[i]; + } + } + } + let ans = 0n; + const mod = 1e9 + 7; + while (k-- > 0) { + let x = 0; + for (let i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + BigInt(x) * BigInt(x)) % BigInt(mod); + } + return Number(ans); +} ``` ### **...** diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.cpp b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.cpp new file mode 100644 index 0000000000000..874f77513c122 --- /dev/null +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + int maxSum(vector& nums, int k) { + int cnt[31]{}; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if (x >> i & 1) { + ++cnt[i]; + } + } + } + long long ans = 0; + const int mod = 1e9 + 7; + while (k--) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i]) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1LL * x * x) % mod; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.go b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.go new file mode 100644 index 0000000000000..c17aae9249166 --- /dev/null +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.go @@ -0,0 +1,22 @@ +func maxSum(nums []int, k int) (ans int) { + cnt := [31]int{} + for _, x := range nums { + for i := 0; i < 31; i++ { + if x>>i&1 == 1 { + cnt[i]++ + } + } + } + const mod int = 1e9 + 7 + for ; k > 0; k-- { + x := 0 + for i := 0; i < 31; i++ { + if cnt[i] > 0 { + x |= 1 << i + cnt[i]-- + } + } + ans = (ans + x*x) % mod + } + return +} \ No newline at end of file diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.java b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.java new file mode 100644 index 0000000000000..3c36491b76594 --- /dev/null +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.java @@ -0,0 +1,25 @@ +class Solution { + public int maxSum(List nums, int k) { + final int mod = (int) 1e9 + 7; + int[] cnt = new int[31]; + for (int x : nums) { + for (int i = 0; i < 31; ++i) { + if ((x >> i & 1) == 1) { + ++cnt[i]; + } + } + } + long ans = 0; + while (k-- > 0) { + int x = 0; + for (int i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + 1L * x * x) % mod; + } + return (int) ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.py b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.py new file mode 100644 index 0000000000000..9410554ecf7e5 --- /dev/null +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.py @@ -0,0 +1,17 @@ +class Solution: + def maxSum(self, nums: List[int], k: int) -> int: + mod = 10**9 + 7 + cnt = [0] * 31 + for x in nums: + for i in range(31): + if x >> i & 1: + cnt[i] += 1 + ans = 0 + for _ in range(k): + x = 0 + for i in range(31): + if cnt[i]: + x |= 1 << i + cnt[i] -= 1 + ans = (ans + x * x) % mod + return ans diff --git a/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.ts b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.ts new file mode 100644 index 0000000000000..7be6371746cc1 --- /dev/null +++ b/solution/2800-2899/2897.Apply Operations on Array to Maximize Sum of Squares/Solution.ts @@ -0,0 +1,23 @@ +function maxSum(nums: number[], k: number): number { + const cnt: number[] = Array(31).fill(0); + for (const x of nums) { + for (let i = 0; i < 31; ++i) { + if ((x >> i) & 1) { + ++cnt[i]; + } + } + } + let ans = 0n; + const mod = 1e9 + 7; + while (k-- > 0) { + let x = 0; + for (let i = 0; i < 31; ++i) { + if (cnt[i] > 0) { + x |= 1 << i; + --cnt[i]; + } + } + ans = (ans + BigInt(x) * BigInt(x)) % BigInt(mod); + } + return Number(ans); +}