diff --git a/README.md b/README.md index f63d34b5a2b17..43dbdfca64534 100644 --- a/README.md +++ b/README.md @@ -197,9 +197,7 @@   how-to-contribute

-[Gitpod.io](https://www.gitpod.io) 是一个免费的在线开发环境,你也可以使用它参与本项目。 - - +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=149001365&machine=basicLinux32gb&location=SoutheastAsia) ## Stars 趋势 diff --git a/README_EN.md b/README_EN.md index 52e116dc70a55..a1b12f59c58c1 100644 --- a/README_EN.md +++ b/README_EN.md @@ -191,9 +191,7 @@ I'm looking for long-term contributors/partners to this repo! Send me [PRs](http   how-to-contribute

-You can also contribute to [doocs/leetcode](https://github.com/doocs/leetcode) using [Gitpod.io](https://www.gitpod.io), a free online dev environment with a single click. - - +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=149001365&machine=basicLinux32gb&location=EastUs) ## Stargazers over time diff --git a/basic/searching/BinarySearch/README.md b/basic/searching/BinarySearch/README.md index 22daa83a7b447..0ac8b9019f901 100644 --- a/basic/searching/BinarySearch/README.md +++ b/basic/searching/BinarySearch/README.md @@ -42,16 +42,16 @@ int search(int left, int right) { } ``` -我们做二分题目时,可以按照以下步骤: +做二分题目时,可以按照以下套路: -1. 写出循环条件:`while (left < right)`,注意是 `left < right`,而非 `left <= right`; -1. 循环体内,先无脑写出 `mid = (left + right) >> 1`; -1. 根据具体题目,实现 `check()` 函数(有时很简单的逻辑,可以不定义 `check`),想一下究竟要用 `right = mid`(模板 1) 还是 `left = mid`(模板 2); - - 如果 `right = mid`,那么无脑写出 else 语句 `left = mid + 1`,并且不需要更改 mid 的计算,即保持 `mid = (left + right) >> 1`; - - 如果 `left = mid`,那么无脑写出 else 语句 `right = mid - 1`,并且在 mid 计算时补充 +1,即 `mid = (left + right + 1) >> 1`。 -1. 循环结束时,left 与 right 相等。 +1. 写出循环条件 $left < right$; +1. 循环体内,不妨先写 $mid = \lfloor \frac{left + right}{2} \rfloor$; +1. 根据具体题目,实现 $check()$ 函数(有时很简单的逻辑,可以不定义 $check$),想一下究竟要用 $right = mid$(模板 $1$) 还是 $left = mid$(模板 $2$); +     - 如果 $right = mid$,那么写出 else 语句 $left = mid + 1$,并且不需要更改 mid 的计算,即保持 $mid = \lfloor \frac{left + right}{2} \rfloor$; +     - 如果 $left = mid$,那么写出 else 语句 $right = mid - 1$,并且在 $mid$ 计算时补充 +1,即 $mid = \lfloor \frac{left + right + 1}{2} \rfloor$; +1. 循环结束时,$left$ 与 $right$ 相等。 -注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 left 或者 right 是否满足题意即可。 +注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 $left$ 或者 $right$ 是否满足题意即可。 ## 例题 diff --git a/basic/searching/BinarySearch/README_EN.md b/basic/searching/BinarySearch/README_EN.md index b62d6130309bc..75541d4883db9 100644 --- a/basic/searching/BinarySearch/README_EN.md +++ b/basic/searching/BinarySearch/README_EN.md @@ -2,6 +2,8 @@ ## Algorithm Templates +The essence of binary search is not "monotonicity", but "boundary". As long as a certain property is found that divides the entire interval into two, the boundary point can be found using binary search. + ### Template 1 ```java @@ -40,6 +42,17 @@ int search(int left, int right) { } ``` +When doing binary search problems, you can follow the following routine: + +1. Write out the loop condition $left < right$; +2. Inside the loop, you might as well write $mid = \lfloor \frac{left + right}{2} \rfloor$ first; +3. According to the specific problem, implement the $check()$ function (sometimes the logic is very simple, you can not define $check$), think about whether to use $right = mid$ (Template $1$) or $left = mid$ (Template $2$); + - If $right = mid$, then write the else statement $left = mid + 1$, and there is no need to change the calculation of $mid$, that is, keep $mid = \lfloor \frac{left + right}{2} \rfloor$; + - If $left = mid$, then write the else statement $right = mid - 1$, and add +1 when calculating $mid$, that is, $mid = \lfloor \frac{left + right + 1}{2} \rfloor$; +4. When the loop ends, $left$ equals $right$. + +Note that the advantage of these two templates is that they always keep the answer within the binary search interval, and the value corresponding to the end condition of the binary search is exactly at the position of the answer. For the case that may have no solution, just check whether the $left$ or $right$ after the binary search ends satisfies the problem. + ## Examples - [Find First and Last Position of Element in Sorted Array](/solution/0000-0099/0034.Find%20First%20and%20Last%20Position%20of%20Element%20in%20Sorted%20Array/README_EN.md) diff --git a/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md b/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md index 45b0058f47232..f4085cc6b610b 100644 --- a/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md +++ b/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md @@ -4,7 +4,7 @@ ## Description -

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 < numbers.length.

+

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

diff --git a/solution/1100-1199/1160.Find Words That Can Be Formed by Characters/README_EN.md b/solution/1100-1199/1160.Find Words That Can Be Formed by Characters/README_EN.md index c9b9b7887af09..0c9012c53f70e 100644 --- a/solution/1100-1199/1160.Find Words That Can Be Formed by Characters/README_EN.md +++ b/solution/1100-1199/1160.Find Words That Can Be Formed by Characters/README_EN.md @@ -6,7 +6,7 @@

You are given an array of strings words and a string chars.

-

A string is good if it can be formed by characters from chars (each character can only be used once).

+

A string is good if it can be formed by characters from chars (each character can only be used once).

Return the sum of lengths of all good strings in words.

diff --git a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README.md b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README.md index 92208ac79f890..2591c48e172a2 100644 --- a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README.md +++ b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README.md @@ -60,7 +60,7 @@ 那么最终答案就是 $n - \max(left[i] + right[i] - 1)$,其中 $1 \leq i \leq n$,并且 $left[i] \gt 1$ 且 $right[i] \gt 1$。 -时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。 @@ -193,8 +193,8 @@ func minimumMountainRemovals(nums []int) int { ```ts function minimumMountainRemovals(nums: number[]): number { const n = nums.length; - const left = new Array(n).fill(1); - const right = new Array(n).fill(1); + const left = Array(n).fill(1); + const right = Array(n).fill(1); for (let i = 1; i < n; ++i) { for (let j = 0; j < i; ++j) { if (nums[i] > nums[j]) { @@ -219,6 +219,41 @@ function minimumMountainRemovals(nums: number[]): number { } ``` +### **TypeScript** + +```ts +impl Solution { + pub fn minimum_mountain_removals(nums: Vec) -> i32 { + let n = nums.len(); + let mut left = vec![1; n]; + let mut right = vec![1; n]; + for i in 1..n { + for j in 0..i { + if nums[i] > nums[j] { + left[i] = left[i].max(left[j] + 1); + } + } + } + for i in (0..n - 1).rev() { + for j in i + 1..n { + if nums[i] > nums[j] { + right[i] = right[i].max(right[j] + 1); + } + } + } + + let mut ans = 0; + for i in 0..n { + if left[i] > 1 && right[i] > 1 { + ans = ans.max(left[i] + right[i] - 1); + } + } + + (n as i32) - ans + } +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README_EN.md b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README_EN.md index 46acbc9147780..0c483fbc51c62 100644 --- a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README_EN.md +++ b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/README_EN.md @@ -46,6 +46,16 @@ ## Solutions +**Solution 1: Dynamic Programming** + +This problem can be transformed into finding the longest increasing subsequence and the longest decreasing subsequence. + +We define $left[i]$ as the length of the longest increasing subsequence ending with $nums[i]$, and define $right[i]$ as the length of the longest decreasing subsequence starting with $nums[i]$. + +Then the final answer is $n - \max(left[i] + right[i] - 1)$, where $1 \leq i \leq n$, and $left[i] \gt 1$ and $right[i] \gt 1$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$. + ### **Python3** @@ -173,8 +183,8 @@ func minimumMountainRemovals(nums []int) int { ```ts function minimumMountainRemovals(nums: number[]): number { const n = nums.length; - const left = new Array(n).fill(1); - const right = new Array(n).fill(1); + const left = Array(n).fill(1); + const right = Array(n).fill(1); for (let i = 1; i < n; ++i) { for (let j = 0; j < i; ++j) { if (nums[i] > nums[j]) { @@ -199,6 +209,41 @@ function minimumMountainRemovals(nums: number[]): number { } ``` +### **TypeScript** + +```ts +impl Solution { + pub fn minimum_mountain_removals(nums: Vec) -> i32 { + let n = nums.len(); + let mut left = vec![1; n]; + let mut right = vec![1; n]; + for i in 1..n { + for j in 0..i { + if nums[i] > nums[j] { + left[i] = left[i].max(left[j] + 1); + } + } + } + for i in (0..n - 1).rev() { + for j in i + 1..n { + if nums[i] > nums[j] { + right[i] = right[i].max(right[j] + 1); + } + } + } + + let mut ans = 0; + for i in 0..n { + if left[i] > 1 && right[i] > 1 { + ans = ans.max(left[i] + right[i] - 1); + } + } + + (n as i32) - ans + } +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.rs b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.rs new file mode 100644 index 0000000000000..96e9c643137f4 --- /dev/null +++ b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.rs @@ -0,0 +1,30 @@ +impl Solution { + pub fn minimum_mountain_removals(nums: Vec) -> i32 { + let n = nums.len(); + let mut left = vec![1; n]; + let mut right = vec![1; n]; + for i in 1..n { + for j in 0..i { + if nums[i] > nums[j] { + left[i] = left[i].max(left[j] + 1); + } + } + } + for i in (0..n - 1).rev() { + for j in i + 1..n { + if nums[i] > nums[j] { + right[i] = right[i].max(right[j] + 1); + } + } + } + + let mut ans = 0; + for i in 0..n { + if left[i] > 1 && right[i] > 1 { + ans = ans.max(left[i] + right[i] - 1); + } + } + + (n as i32) - ans + } +} diff --git a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.ts b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.ts index cc447ceb23d7f..235ea8f163053 100644 --- a/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.ts +++ b/solution/1600-1699/1671.Minimum Number of Removals to Make Mountain Array/Solution.ts @@ -1,7 +1,7 @@ function minimumMountainRemovals(nums: number[]): number { const n = nums.length; - const left = new Array(n).fill(1); - const right = new Array(n).fill(1); + const left = Array(n).fill(1); + const right = Array(n).fill(1); for (let i = 1; i < n; ++i) { for (let j = 0; j < i; ++j) { if (nums[i] > nums[j]) { diff --git a/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README.md b/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README.md index 0c9d567adc4f0..d54248ce22f05 100644 --- a/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README.md +++ b/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README.md @@ -80,7 +80,7 @@ nums[3] + nums[0] = 3 + 1 = 4. 可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。 diff --git a/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README_EN.md b/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README_EN.md index 9ee7af3515036..b1429576b6fdc 100644 --- a/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README_EN.md +++ b/solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README_EN.md @@ -52,6 +52,30 @@ Therefore, nums[i] + nums[n-1-i] = 4 for every i, so nums is complementary. ## Solutions +**Solution 1: Difference Array** + +Let's denote $a$ as the smaller value between $nums[i]$ and $nums[n-i-1]$, and $b$ as the larger value between $nums[i]$ and $nums[n-i-1]$. + +Suppose that after replacement, the sum of the two numbers is $x$. From the problem, we know that the minimum value of $x$ is $2$, which means both numbers are replaced by $1$; the maximum value is $2 \times limit$, which means both numbers are replaced by $limit$. Therefore, the range of $x$ is $[2,... 2 \times limit]$. + +How to find the minimum number of replacements for different $x$? + +We analyze and find: + +- If $x = a + b$, then the number of replacements we need is $0$, which means the current pair of numbers already meets the complement requirement; +- Otherwise, if $1 + a \le x \le limit + b $, then the number of replacements we need is $1$, which means we can replace one of the numbers; +- Otherwise, if $2 \le x \le 2 \times limit$, then the number of replacements we need is $2$, which means we need to replace both numbers. + +Therefore, we can iterate over each pair of numbers and perform the following operations: + +1. First, add $2$ to the number of operations required in the range $[2,... 2 \times limit]$. +1. Then, subtract $1$ from the number of operations required in the range $[1 + a,... limit + b]$. +1. Finally, subtract $1$ from the number of operations required in the range $[a + b,... a + b]$. + +We can see that this is actually adding and subtracting elements in a continuous interval, so we can use a difference array to implement it. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$. + ### **Python3** diff --git a/solution/1600-1699/1675.Minimize Deviation in Array/README_EN.md b/solution/1600-1699/1675.Minimize Deviation in Array/README_EN.md index bd2f74e720f22..65a7366b82fa0 100644 --- a/solution/1600-1699/1675.Minimize Deviation in Array/README_EN.md +++ b/solution/1600-1699/1675.Minimize Deviation in Array/README_EN.md @@ -60,6 +60,18 @@ ## Solutions +**Solution 1: Greedy + Priority Queue** + +Intuitively, to get the minimum offset of the array, we need to decrease the maximum value of the array and increase the minimum value of the array. + +Since there are two operations that can be performed each time: multiply an odd number by $2$; divide an even number by $2$, the situation is more complex. We can multiply all odd numbers by $2$ to convert them into even numbers, which is equivalent to having only one division operation. The division operation can only reduce a certain number, and only by reducing the maximum value can the result be more optimal. + +Therefore, we use a priority queue (max heap) to maintain the maximum value of the array. Each time we take out the top element of the heap for division operation, put the new value into the heap, and update the minimum value and the minimum value of the difference between the top element of the heap and the minimum value. + +When the top element of the heap is an odd number, the operation stops. + +The time complexity is $O(n\log n \times \log m)$. Where $n$ and $m$ are the length of the array `nums` and the maximum element of the array, respectively. Since the maximum element in the array is divided by $2$ at most $O(\log m)$ times, all elements are divided by $2$ at most $O(n\log m)$ times. Each time the heap is popped and put into operation, the time complexity is $O(\log n)$. Therefore, the total time complexity is $O(n\log n \times \log m)$. + ### **Python3** diff --git a/solution/1600-1699/1678.Goal Parser Interpretation/README_EN.md b/solution/1600-1699/1678.Goal Parser Interpretation/README_EN.md index 70fd97acc9527..cf6aec728af88 100644 --- a/solution/1600-1699/1678.Goal Parser Interpretation/README_EN.md +++ b/solution/1600-1699/1678.Goal Parser Interpretation/README_EN.md @@ -45,6 +45,21 @@ The final concatenated result is "Goal". ## Solutions +**Solution 1: String Replacement** + +According to the problem, we only need to replace `"()"` with `'o'` and `"(al)"` with `"al"` in the string `command`. + +**Solution 2: String Iteration** + +We can also iterate over the string `command`. For each character $c$: + +- If it is `'G'`, directly add $c$ to the result string; +- If it is `'('`, check if the next character is `')'`. If it is, add `'o'` to the result string. Otherwise, add `"al"` to the result string. + +After the iteration, return the result string. + +The time complexity is $O(n)$, and the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1679.Max Number of K-Sum Pairs/README.md b/solution/1600-1699/1679.Max Number of K-Sum Pairs/README.md index 78f0ace35c224..5d0eeb81c6323 100644 --- a/solution/1600-1699/1679.Max Number of K-Sum Pairs/README.md +++ b/solution/1600-1699/1679.Max Number of K-Sum Pairs/README.md @@ -49,7 +49,7 @@ **方法一:排序** -我们对 `nums` 进行排序。然后 $l$, $r$ 分别指向 `nums` 首尾元素,判断两整数之和 $s$ 与 $k$ 的大小关系。 +我们对 $nums$ 进行排序。然后 $l$, $r$ 分别指向 $nums$ 首尾元素,判断两整数之和 $s$ 与 $k$ 的大小关系。 - 若 $s = k$,说明找到了两个整数,满足和为 $k$,答案加一,然后 $l$, $r$ 向中间移动; - 若 $s \gt k$,则 $r$ 指针向左移动; @@ -58,17 +58,17 @@ 循环结束,返回答案。 -时间复杂度 $O(n\times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为 `nums` 的长度。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为 $nums$ 的长度。 **方法二:哈希表** -我们使用哈希表 `cnt` 记录当前剩余整数及其出现的次数。 +我们使用哈希表 $cnt$ 记录当前剩余整数及其出现的次数。 -遍历 `nums`,对于当前整数 $x$,判断 $k - x$ 是否在 `cnt` 中,若存在,则说明找到了两个整数,满足和为 $k$,答案加一,然后将 $k - x$ 的出现次数减一;否则,将 $x$ 的出现次数加一。 +遍历 $nums$,对于当前整数 $x$,判断 $k - x$ 是否在 $cnt$ 中,若存在,则说明找到了两个整数,满足和为 $k$,答案加一,然后将 $k - x$ 的出现次数减一;否则,将 $x$ 的出现次数加一。 遍历结束,返回答案。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `nums` 的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 $nums$ 的长度。 diff --git a/solution/1600-1699/1679.Max Number of K-Sum Pairs/README_EN.md b/solution/1600-1699/1679.Max Number of K-Sum Pairs/README_EN.md index f32579d1cf0b7..a0eb5cd7669ea 100644 --- a/solution/1600-1699/1679.Max Number of K-Sum Pairs/README_EN.md +++ b/solution/1600-1699/1679.Max Number of K-Sum Pairs/README_EN.md @@ -41,6 +41,29 @@ There are no more pairs that sum up to 6, hence a total of 1 operation. ## Solutions +**Solution 1: Sorting** + +We sort $nums$. Then $l$ and $r$ point to the first and last elements of $nums$ respectively, and we compare the sum $s$ of the two integers with $k$. + +- If $s = k$, it means that we have found two integers whose sum is $k$. We increment the answer and then move $l$ and $r$ towards the middle; +- If $s > k$, then we move the $r$ pointer to the left; +- If $s < k$, then we move the $l$ pointer to the right; +- We continue the loop until $l \geq r$. + +After the loop ends, we return the answer. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of $nums$. + +**Solution 2: Hash Table** + +We use a hash table $cnt$ to record the current remaining integers and their occurrence counts. + +We iterate over $nums$. For the current integer $x$, we check if $k - x$ is in $cnt$. If it exists, it means that we have found two integers whose sum is $k$. We increment the answer and then decrement the occurrence count of $k - x$; otherwise, we increment the occurrence count of $x$. + +After the iteration ends, we return the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of $nums$. + ### **Python3** diff --git a/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README.md b/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README.md index ee15a29fc66c8..a611a068b7b51 100644 --- a/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README.md +++ b/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README.md @@ -50,7 +50,7 @@ 观察数字的连接规律,我们可以发现,当连接到第 $i$ 个数时,实际上是将前 $i-1$ 个数连接而成的结果 $ans$ 往左移动一定的位数,然后再加上 $i$ 这个数,移动的位数 $shift$ 是 $i$ 中二进制的位数。由于 $i$ 在不断加 $1$,移动的位数要么与上一次移动的位数保持不变,要么加一。当 $i$ 为 $2$ 的幂次方的时候,也即是说 $i$ 的二进制数中只有一位是 $1$ 时,移动的位数相比于上次加 $1$。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为给定的整数。 +时间复杂度 $O(n)$,其中 $n$ 为给定的整数。空间复杂度 $O(1)$。 diff --git a/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README_EN.md b/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README_EN.md index ff0fe7f7410d6..327a29556a8ab 100644 --- a/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README_EN.md +++ b/solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README_EN.md @@ -43,6 +43,12 @@ After modulo 109 + 7, the result is 505379714. ## Solutions +**Solution 1: Bit Manipulation** + +By observing the pattern of number concatenation, we can find that when concatenating to the $i$-th number, the result $ans$ formed by concatenating the previous $i-1$ numbers is actually shifted to the left by a certain number of bits, and then $i$ is added. The number of bits shifted, $shift$, is the number of binary digits in $i$. Since $i$ is continuously incremented by $1$, the number of bits shifted either remains the same as the last shift or increases by one. When $i$ is a power of $2$, that is, when there is only one bit in the binary number of $i$ that is $1$, the number of bits shifted increases by $1$ compared to the last time. + +The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1681.Minimum Incompatibility/README_EN.md b/solution/1600-1699/1681.Minimum Incompatibility/README_EN.md index a580e46978b97..6b9e0636b051f 100644 --- a/solution/1600-1699/1681.Minimum Incompatibility/README_EN.md +++ b/solution/1600-1699/1681.Minimum Incompatibility/README_EN.md @@ -50,6 +50,22 @@ The incompatibility is (2-1) + (3-2) + (8-6) + (3-1) = 6. ## Solutions +**Solution 1: Preprocessing + State Compression + Dynamic Programming** + +Let's assume that the size of each subset after partitioning is $m$, so $m=\frac{n}{k}$, where $n$ is the length of the array. + +We can enumerate all subsets $i$, where $i \in [0, 2^n)$, if the binary representation of subset $i$ has $m$ ones, and the elements in subset $i$ are not repeated, then we can calculate the incompatibility of subset $i$, denoted as $g[i]$, i.e., $g[i]=\max_{j \in i} \{nums[j]\} - \min_{j \in i} \{nums[j]\}$. + +Next, we can use dynamic programming to solve. + +We define $f[i]$ as the minimum sum of incompatibilities when the current partitioned subset state is $i$. Initially, $f[0]=0$, which means no elements are partitioned into the subset, and the rest $f[i]=+\infty$. + +For state $i$, we find all undivided and non-repeated elements, represented by a state $mask$. If the number of elements in state $mask$ is greater than or equal to $m$, then we enumerate all subsets $j$ of $mask$, and satisfy $j \subset mask$, then $f[i \cup j]=\min \{f[i \cup j], f[i]+g[j]\}$. + +Finally, if $f[2^n-1]=+\infty$, it means that it cannot be partitioned into $k$ subsets, return $-1$, otherwise return $f[2^n-1]$. + +The time complexity is $O(3^n)$, and the space complexity is $O(2^n)$. Here, $n$ is the length of the array. + ### **Python3** diff --git a/solution/1600-1699/1682.Longest Palindromic Subsequence II/README_EN.md b/solution/1600-1699/1682.Longest Palindromic Subsequence II/README_EN.md index ddbf89d66e546..74d69ad05cf4f 100644 --- a/solution/1600-1699/1682.Longest Palindromic Subsequence II/README_EN.md +++ b/solution/1600-1699/1682.Longest Palindromic Subsequence II/README_EN.md @@ -44,6 +44,20 @@ ## Solutions +**Solution 1: Memorization Search** + +We design a function $dfs(i, j, x)$ to represent the length of the longest "good" palindrome subsequence ending with character $x$ in the index range $[i, j]$ of string $s$. The answer is $dfs(0, n - 1, 26)$. + +The calculation process of the function $dfs(i, j, x)$ is as follows: + +- If $i >= j$, then $dfs(i, j, x) = 0$; +- If $s[i] = s[j]$ and $s[i] \neq x$, then $dfs(i, j, x) = dfs(i + 1, j - 1, s[i]) + 2$; +- If $s[i] \neq s[j]$, then $dfs(i, j, x) = max(dfs(i + 1, j, x), dfs(i, j - 1, x))$. + +During the process, we can use memorization search to avoid repeated calculations. + +The time complexity is $O(n^2 \times C)$. Where $n$ is the length of the string $s$, and $C$ is the size of the character set. In this problem, $C = 26$. + ### **Python3** diff --git a/solution/1600-1699/1684.Count the Number of Consistent Strings/README.md b/solution/1600-1699/1684.Count the Number of Consistent Strings/README.md index 92de0807d7cdf..34e665744e857 100644 --- a/solution/1600-1699/1684.Count the Number of Consistent Strings/README.md +++ b/solution/1600-1699/1684.Count the Number of Consistent Strings/README.md @@ -66,7 +66,7 @@ 回到题目上,判断一个字符串 $w$ 是否由 `allowed` 中的字符组成,就可以转换为:判断 $f(allowed)$ 和 $f(w)$ 进行按位或运算后的结果是否等于 $f(allowed)$。若是,答案加一。 -时间复杂度 $O(m)$,空间复杂度 $O(1)$。其中 $m$ 为所有字符串的总长度。 +时间复杂度 $O(m)$,其中 $m$ 为所有字符串的总长度。空间复杂度 $O(1)$。 diff --git a/solution/1600-1699/1684.Count the Number of Consistent Strings/README_EN.md b/solution/1600-1699/1684.Count the Number of Consistent Strings/README_EN.md index 2d9d38e86bf12..8955025943bf1 100644 --- a/solution/1600-1699/1684.Count the Number of Consistent Strings/README_EN.md +++ b/solution/1600-1699/1684.Count the Number of Consistent Strings/README_EN.md @@ -46,6 +46,22 @@ ## Solutions +**Solution 1: Hash Table or Array** + +A straightforward approach is to use a hash table or array $s$ to record the characters in `allowed`. Then iterate over the `words` array, for each string $w$, determine whether it is composed of characters in `allowed`. If so, increment the answer. + +The time complexity is $O(m)$, and the space complexity is $O(C)$. Here, $m$ is the total length of all strings, and $C$ is the size of the character set `allowed`. In this problem, $C \leq 26$. + +**Solution 2: Bit Manipulation** + +We can also use a single integer to represent the occurrence of characters in each string. In this integer, each bit in the binary representation indicates whether a character appears. + +We simply define a function $f(w)$ that can convert a string $w$ into an integer. Each bit in the binary representation of the integer indicates whether a character appears. For example, the string `ab` can be converted into the integer $3$, which is represented in binary as $11$. The string `abd` can be converted into the integer $11$, which is represented in binary as $1011$. + +Back to the problem, to determine whether a string $w$ is composed of characters in `allowed`, we can check whether the result of the bitwise OR operation between $f(allowed)$ and $f(w)$ is equal to $f(allowed)$. If so, increment the answer. + +The time complexity is $O(m)$, where $m$ is the total length of all strings. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README.md b/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README.md index 304853838db24..408539f1915c3 100644 --- a/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README.md +++ b/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README.md @@ -47,11 +47,11 @@ result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5。 **方法一:求和 + 枚举** -我们先求出数组 `nums` 所有元素的和,记为 $s$,用变量 $t$ 记录当前已经枚举过的元素之和。 +我们先求出数组 $nums$ 所有元素的和,记为 $s$,用变量 $t$ 记录当前已经枚举过的元素之和。 接下来枚举 $nums[i]$,那么 $ans[i] = nums[i] \times i - t + s - t - nums[i] \times (n - i)$,然后我们更新 $t$,即 $t = t + nums[i]$。继续枚举下一个元素,直到枚举完所有元素。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。 diff --git a/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README_EN.md b/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README_EN.md index 42a4fcae266d8..8ddeb18d733fa 100644 --- a/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README_EN.md +++ b/solution/1600-1699/1685.Sum of Absolute Differences in a Sorted Array/README_EN.md @@ -39,6 +39,14 @@ result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5. ## Solutions +**Solution 1: Summation + Enumeration** + +First, we calculate the sum of all elements in the array $nums$, denoted as $s$. We use a variable $t$ to record the sum of the elements that have been enumerated so far. + +Next, we enumerate $nums[i]$. Then $ans[i] = nums[i] \times i - t + s - t - nums[i] \times (n - i)$. After that, we update $t$, i.e., $t = t + nums[i]$. We continue to enumerate the next element until all elements are enumerated. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1686.Stone Game VI/README.md b/solution/1600-1699/1686.Stone Game VI/README.md index 3091e4e47a70d..259cd2f0203ae 100644 --- a/solution/1600-1699/1686.Stone Game VI/README.md +++ b/solution/1600-1699/1686.Stone Game VI/README.md @@ -74,7 +74,7 @@ Bob 会获胜。 选取石头的最优化的策略是,让自己得分最高,同时让对手失分最多。因此,我们创建一个数组 `arr`,其中 `arr[i] = aliceValues[i] + bobValues[i]`,然后对 `arr` 进行降序排序。然后,我们从 `arr` 中取出石头,每次取出两个石头,分别给 Alice 和 Bob,直到 `arr` 中没有石头为止。最后,我们比较 Alice 和 Bob 的得分,得分高的人获胜。 -时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `aliceValues` 和 `bobValues` 的长度。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `aliceValues` 和 `bobValues` 的长度。 diff --git a/solution/1600-1699/1686.Stone Game VI/README_EN.md b/solution/1600-1699/1686.Stone Game VI/README_EN.md index 3a1bc061e6802..2144944556eb1 100644 --- a/solution/1600-1699/1686.Stone Game VI/README_EN.md +++ b/solution/1600-1699/1686.Stone Game VI/README_EN.md @@ -64,6 +64,12 @@ Bob wins. ## Solutions +**Solution 1: Greedy + Sorting** + +The optimal strategy for picking stones is to maximize one's own score while making the opponent lose as much as possible. Therefore, we create an array `arr`, where `arr[i] = aliceValues[i] + bobValues[i]`, and then sort `arr` in descending order. Then, we take stones from `arr`, taking two stones each time, one for Alice and one for Bob, until there are no stones left in `arr`. Finally, we compare the scores of Alice and Bob, and the person with the higher score wins. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the arrays `aliceValues` and `bobValues`. + ### **Python3** diff --git a/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README.md b/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README.md index 01853b769b9bd..d8731e450f4ca 100644 --- a/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README.md +++ b/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README.md @@ -228,7 +228,7 @@ func boxDelivering(boxes [][]int, portsCount int, maxBoxes int, maxWeight int) i 本题数据规模达到 $10^5$,而以上代码的时间复杂度为 $O(n^2)$,会超出时间限制。我们仔细观察: $$ -f[i] = min(f[i], f[j] + cs[i - 1] - cs[j] + 2) +f[i] = \min(f[i], f[j] + cs[i - 1] - cs[j] + 2) $$ 实际上我们是要在 $[i-maxBoxes,..i-1]$ 这个窗口内找到一个 $j$,使得 $f[j] - cs[j]$ 的值最小,求滑动窗口的最小值,一种常用的做法是使用单调队列,可以在 $O(1)$ 时间内获取到满足条件的最小值。 diff --git a/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README_EN.md b/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README_EN.md index e0a329954526a..514b169e5a0f6 100644 --- a/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README_EN.md +++ b/solution/1600-1699/1687.Delivering Boxes from Storage to Ports/README_EN.md @@ -74,6 +74,146 @@ So the total number of trips is 2 + 2 + 2 = 6. ## Solutions +**Solution 1: Dynamic Programming + Monotonic Queue Optimization** + +We define $f[i]$ as the minimum number of trips required to transport the first $i$ boxes from the warehouse to the corresponding docks, so the answer is $f[n]$. + +The boxes need to be transported in the order of the array. Each time, the truck will take out several consecutive boxes in order, then deliver them to the corresponding docks one by one. After all are delivered, it returns to the warehouse. + +Therefore, we can enumerate the index $j$ of the last box transported in the last trip. Then $f[i]$ can be transferred from $f[j]$. During the transfer, we need to consider the following issues: + +- When transferring from $f[j]$, the number of boxes on the truck cannot exceed $maxBoxes$ +- When transferring from $f[j]$, the total weight of the boxes on the truck cannot exceed $maxWeight$ + +The state transition equation is: + +$$ +f[i] = \min_{j \in [i - maxBoxes, i - 1]} \left(f[j] + \sum_{k = j + 1}^i \text{cost}(k)\right) +$$ + +Where $\sum_{k = j + 1}^i \text{cost}(k)$ represents the number of trips required to deliver the boxes in $[j+1,..i]$ to their corresponding docks in one trip. This part of the trip count can be quickly calculated using prefix sums. + +For example, suppose we take out boxes $1, 2, 3$ and need to deliver them to docks $4, 4, 5$. We first go from the warehouse to dock $4$, then from dock $4$ to dock $5$, and finally from dock $5$ back to the warehouse. It can be seen that it takes $2$ trips to go from the warehouse to the dock and from the dock back to the warehouse. The number of trips from dock to dock depends on whether the two adjacent docks are the same. If they are not the same, the number of trips will increase by $1$, otherwise it remains the same. Therefore, we can calculate the number of trips between docks using prefix sums, and add two trips for the start and end, to calculate the number of trips required to deliver the boxes in $[j+1,..i]$ to their corresponding docks. + +The code implementation is as follows: + +```python +# 33/39 +class Solution: + def boxDelivering( + self, boxes: List[List[int]], portsCount: int, maxBoxes: int, maxWeight: int + ) -> int: + n = len(boxes) + ws = list(accumulate((box[1] for box in boxes), initial=0)) + c = [int(a != b) for a, b in pairwise(box[0] for box in boxes)] + cs = list(accumulate(c, initial=0)) + f = [inf] * (n + 1) + f[0] = 0 + for i in range(1, n + 1): + for j in range(max(0, i - maxBoxes), i): + if ws[i] - ws[j] <= maxWeight: + f[i] = min(f[i], f[j] + cs[i - 1] - cs[j] + 2) + return f[n] +``` + +```java +// 35/39 +class Solution { + public int boxDelivering(int[][] boxes, int portsCount, int maxBoxes, int maxWeight) { + int n = boxes.length; + long[] ws = new long[n + 1]; + int[] cs = new int[n]; + for (int i = 0; i < n; ++i) { + int p = boxes[i][0], w = boxes[i][1]; + ws[i + 1] = ws[i] + w; + if (i < n - 1) { + cs[i + 1] = cs[i] + (p != boxes[i + 1][0] ? 1 : 0); + } + } + int[] f = new int[n + 1]; + Arrays.fill(f, 1 << 30); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + for (int j = Math.max(0, i - maxBoxes); j < i; ++j) { + if (ws[i] - ws[j] <= maxWeight) { + f[i] = Math.min(f[i], f[j] + cs[i - 1] - cs[j] + 2); + } + } + } + return f[n]; + } +} +``` + +```cpp +// 35/39 +class Solution { +public: + int boxDelivering(vector>& boxes, int portsCount, int maxBoxes, int maxWeight) { + int n = boxes.size(); + long ws[n + 1]; + int cs[n]; + ws[0] = cs[0] = 0; + for (int i = 0; i < n; ++i) { + int p = boxes[i][0], w = boxes[i][1]; + ws[i + 1] = ws[i] + w; + if (i < n - 1) cs[i + 1] = cs[i] + (p != boxes[i + 1][0]); + } + int f[n + 1]; + memset(f, 0x3f, sizeof f); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + for (int j = max(0, i - maxBoxes); j < i; ++j) { + if (ws[i] - ws[j] <= maxWeight) { + f[i] = min(f[i], f[j] + cs[i - 1] - cs[j] + 2); + } + } + } + return f[n]; + } +}; +``` + +```go +// 35/39 +func boxDelivering(boxes [][]int, portsCount int, maxBoxes int, maxWeight int) int { + n := len(boxes) + ws := make([]int, n+1) + cs := make([]int, n) + for i, box := range boxes { + p, w := box[0], box[1] + ws[i+1] = ws[i] + w + if i < n-1 { + t := 0 + if p != boxes[i+1][0] { + t++ + } + cs[i+1] = cs[i] + t + } + } + f := make([]int, n+1) + for i := 1; i <= n; i++ { + f[i] = 1 << 30 + for j := max(0, i-maxBoxes); j < i; j++ { + if ws[i]-ws[j] <= maxWeight { + f[i] = min(f[i], f[j]+cs[i-1]-cs[j]+2) + } + } + } + return f[n] +} +``` + +The data scale of this problem reaches $10^5$, and the time complexity of the above code is $O(n^2)$, which will exceed the time limit. If we observe carefully: + +$$ +f[i] = \min(f[i], f[j] + cs[i - 1] - cs[j] + 2) +$$ + +In fact, we are looking for a $j$ in the window $[i-maxBoxes,..i-1]$ that minimizes the value of $f[j] - cs[j]$. To find the minimum value in a sliding window, a common method is to use a monotonic queue, which can get the minimum value that meets the condition in $O(1)$ time. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of boxes in the problem. + ### **Python3** diff --git a/solution/1600-1699/1688.Count of Matches in Tournament/README_EN.md b/solution/1600-1699/1688.Count of Matches in Tournament/README_EN.md index c50b2c1d9f191..e010bbf8300f6 100644 --- a/solution/1600-1699/1688.Count of Matches in Tournament/README_EN.md +++ b/solution/1600-1699/1688.Count of Matches in Tournament/README_EN.md @@ -48,6 +48,12 @@ Total number of matches = 7 + 3 + 2 + 1 = 13. ## Solutions +**Solution 1: Quick Thinking** + +From the problem description, we know that there are $n$ teams in total. Each pairing will eliminate one team. Therefore, the number of pairings is equal to the number of teams eliminated, which is $n - 1$. + +The time complexity is $O(1)$, and the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README.md b/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README.md index 058758548a3bb..096c65ba84b65 100644 --- a/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README.md +++ b/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README.md @@ -49,7 +49,7 @@ 题目等价于找字符串中的最大数。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串长度。 +时间复杂度 $O(n)$,其中 $n$ 为字符串长度。空间复杂度 $O(1)$。 diff --git a/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README_EN.md b/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README_EN.md index 3d9af94570b29..83b2b13c1e64b 100644 --- a/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README_EN.md +++ b/solution/1600-1699/1689.Partitioning Into Minimum Number Of Deci-Binary Numbers/README_EN.md @@ -42,6 +42,12 @@ ## Solutions +**Solution 1: Quick Thinking** + +The problem is equivalent to finding the maximum number in the string. + +The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1600-1699/1690.Stone Game VII/README_EN.md b/solution/1600-1699/1690.Stone Game VII/README_EN.md index 12f4a7e7748f3..42abd46bff4b7 100644 --- a/solution/1600-1699/1690.Stone Game VII/README_EN.md +++ b/solution/1600-1699/1690.Stone Game VII/README_EN.md @@ -44,6 +44,21 @@ The score difference is 18 - 12 = 6. ## Solutions +**Solution 1: Memorization Search** + +First, we preprocess to get the prefix sum array $s$, where $s[i]$ represents the total sum of the first $i$ stones. + +Next, we design a function $dfs(i, j)$, which represents the score difference between the first and second players when the remaining stones are $stones[i], stones[i + 1], \dots, stones[j]$. The answer is $dfs(0, n - 1)$. + +The calculation process of the function $dfs(i, j)$ is as follows: + +- If $i > j$, it means there are no stones currently, so return $0$; +- Otherwise, the first player has two choices, which are to remove $stones[i]$ or $stones[j]$, and then calculate the score difference, i.e., $a = s[j + 1] - s[i + 1] - dfs(i + 1, j)$ and $b = s[j] - s[i] - dfs(i, j - 1)$. We take the larger of the two as the return value of $dfs(i, j)$. + +During the process, we use memorization search, i.e., use an array $f$ to record the return value of the function $dfs(i, j)$, to avoid repeated calculations. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the number of stones. + ### **Python3** diff --git a/solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README_EN.md b/solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README_EN.md index 60ff3a2235075..82a9e018fb25d 100644 --- a/solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README_EN.md +++ b/solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README_EN.md @@ -57,6 +57,28 @@ The maximum height of stacked cuboids is 6 * 17 = 102. ## Solutions +**Solution 1: Sorting + Dynamic Programming** + +According to the problem description, box $j$ can be placed on box $i$ if and only if the "length, width, and height" of box $j$ are less than or equal to the "length, width, and height" of box $i$. + +This problem allows us to rotate the boxes, which means we can choose any side of the box as the "height". For any legal stacking, if we rotate each box in it to "length <= width <= height", the stacking is still legal and can ensure the maximum height of the stacking. + +Therefore, we can sort all the sides of the boxes so that each box satisfies "length <= width <= height". Then we sort each box in ascending order. + +Next, we can use dynamic programming to solve this problem. + +We define $f[i]$ as the maximum height when box $i$ is at the bottom. We can enumerate each box $j$ above box $i$, where $0 \leq j < i$. If $j$ can be placed on top of $i$, then we can get the state transition equation: + +$$ +f[i] = \max_{0 \leq j < i} \{f[j] + h[i]\} +$$ + +where $h[i]$ represents the height of box $i$. + +The final answer is the maximum value of $f[i]$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the number of boxes. + ### **Python3** diff --git a/solution/1600-1699/1692.Count Ways to Distribute Candies/README.md b/solution/1600-1699/1692.Count Ways to Distribute Candies/README.md index 03e3f9ba20131..6fcb52db1116d 100644 --- a/solution/1600-1699/1692.Count Ways to Distribute Candies/README.md +++ b/solution/1600-1699/1692.Count Ways to Distribute Candies/README.md @@ -155,6 +155,24 @@ func waysToDistribute(n int, k int) int { } ``` +### **TypeScript** + +```ts +function waysToDistribute(n: number, k: number): number { + const mod = 10 ** 9 + 7; + const f: number[][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 1 }, () => 0), + ); + f[0][0] = 1; + for (let i = 1; i <= n; ++i) { + for (let j = 1; j <= k; ++j) { + f[i][j] = (f[i - 1][j] * j + f[i - 1][j - 1]) % mod; + } + } + return f[n][k]; +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1692.Count Ways to Distribute Candies/README_EN.md b/solution/1600-1699/1692.Count Ways to Distribute Candies/README_EN.md index 5d30a7c0f6021..ce13975d87e49 100644 --- a/solution/1600-1699/1692.Count Ways to Distribute Candies/README_EN.md +++ b/solution/1600-1699/1692.Count Ways to Distribute Candies/README_EN.md @@ -58,6 +58,20 @@ ## Solutions +**Solution 1: Dynamic Programming** + +We define $f[i][j]$ as the number of different ways to distribute $i$ candies to $j$ bags. Initially, $f[0][0]=1$, and the answer is $f[n][k]$. + +We consider how to distribute the $i$-th candy. If the $i$-th candy is distributed to a new bag, then $f[i][j]=f[i-1][j-1]$. If the $i$-th candy is distributed to an existing bag, then $f[i][j]=f[i-1][j]\times j$. Therefore, the state transition equation is: + +$$ +f[i][j]=f[i-1][j-1]+f[i-1][j]\times j +$$ + +The final answer is $f[n][k]$. + +The time complexity is $O(n \times k)$, and the space complexity is $O(n \times k)$. Here, $n$ and $k$ are the number of candies and bags, respectively. + ### **Python3** @@ -131,6 +145,24 @@ func waysToDistribute(n int, k int) int { } ``` +### **TypeScript** + +```ts +function waysToDistribute(n: number, k: number): number { + const mod = 10 ** 9 + 7; + const f: number[][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 1 }, () => 0), + ); + f[0][0] = 1; + for (let i = 1; i <= n; ++i) { + for (let j = 1; j <= k; ++j) { + f[i][j] = (f[i - 1][j] * j + f[i - 1][j - 1]) % mod; + } + } + return f[n][k]; +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1692.Count Ways to Distribute Candies/Solution.ts b/solution/1600-1699/1692.Count Ways to Distribute Candies/Solution.ts new file mode 100644 index 0000000000000..1e95933f88c40 --- /dev/null +++ b/solution/1600-1699/1692.Count Ways to Distribute Candies/Solution.ts @@ -0,0 +1,13 @@ +function waysToDistribute(n: number, k: number): number { + const mod = 10 ** 9 + 7; + const f: number[][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 1 }, () => 0), + ); + f[0][0] = 1; + for (let i = 1; i <= n; ++i) { + for (let j = 1; j <= k; ++j) { + f[i][j] = (f[i - 1][j] * j + f[i - 1][j - 1]) % mod; + } + } + return f[n][k]; +} diff --git a/solution/1600-1699/1694.Reformat Phone Number/README.md b/solution/1600-1699/1694.Reformat Phone Number/README.md index 0115e0288e5d0..16d2e32fa98ed 100644 --- a/solution/1600-1699/1694.Reformat Phone Number/README.md +++ b/solution/1600-1699/1694.Reformat Phone Number/README.md @@ -89,7 +89,7 @@ **方法一:简单模拟** -先按照题意,去除字符串中的所有空格和破折号。 +我们先按照题意,去除字符串中的所有空格和破折号。 记当前字符串长度为 $n$,然后从前往后遍历字符串,每 $3$ 个字符为一组,将其加入结果字符串中,共取 $n / 3$ 组。 diff --git a/solution/1600-1699/1694.Reformat Phone Number/README_EN.md b/solution/1600-1699/1694.Reformat Phone Number/README_EN.md index 038becf2e7c94..47b0fcf8a4f5e 100644 --- a/solution/1600-1699/1694.Reformat Phone Number/README_EN.md +++ b/solution/1600-1699/1694.Reformat Phone Number/README_EN.md @@ -64,6 +64,18 @@ Joining the blocks gives "123-456-78". ## Solutions +**Solution 1: Simple Simulation** + +First, according to the problem description, we remove all spaces and hyphens from the string. + +Let the current string length be $n$. Then we traverse the string from the beginning, grouping every $3$ characters together and adding them to the result string. We take a total of $n / 3$ groups. + +If there is $1$ character left in the end, we form a new group of two characters with the last character of the last group and this character, and add it to the result string. If there are $2$ characters left, we directly form a new group with these two characters and add it to the result string. + +Finally, we add hyphens between all groups and return the result string. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string. + ### **Python3** diff --git a/solution/1600-1699/1695.Maximum Erasure Value/README.md b/solution/1600-1699/1695.Maximum Erasure Value/README.md index 34662bd76e697..12dd265db16cc 100644 --- a/solution/1600-1699/1695.Maximum Erasure Value/README.md +++ b/solution/1600-1699/1695.Maximum Erasure Value/README.md @@ -49,7 +49,7 @@ 遍历数组,对于每个数字 $v$,如果 $d[v]$ 存在,那么我们更新 $j$ 为 $max(j, d[v])$,这样就保证了当前不重复子数组不包含 $v$,然后更新答案为 $max(ans, s[i] - s[j])$,最后更新 $d[v]$ 为 $i$。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。 @@ -140,6 +140,27 @@ func maximumUniqueSubarray(nums []int) (ans int) { } ``` +### **TypeScript** + +```ts +function maximumUniqueSubarray(nums: number[]): number { + const m = Math.max(...nums); + const n = nums.length; + const s: number[] = Array.from({ length: n + 1 }, () => 0); + for (let i = 1; i <= n; ++i) { + s[i] = s[i - 1] + nums[i - 1]; + } + const d = Array.from({ length: m + 1 }, () => 0); + let [ans, j] = [0, 0]; + for (let i = 1; i <= n; ++i) { + j = Math.max(j, d[nums[i - 1]]); + ans = Math.max(ans, s[i] - s[j]); + d[nums[i - 1]] = i; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1695.Maximum Erasure Value/README_EN.md b/solution/1600-1699/1695.Maximum Erasure Value/README_EN.md index d66b316c34003..a9adb5e203913 100644 --- a/solution/1600-1699/1695.Maximum Erasure Value/README_EN.md +++ b/solution/1600-1699/1695.Maximum Erasure Value/README_EN.md @@ -37,6 +37,14 @@ ## Solutions +**Solution 1: Array or Hash Table + Prefix Sum** + +We use an array or hash table $d$ to record the last occurrence of each number, use $s$ to record the prefix sum, and use $j$ to record the left endpoint of the current non-repeating subarray. + +We traverse the array, for each number $v$, if $d[v]$ exists, then we update $j$ to $max(j, d[v])$, which ensures that the current non-repeating subarray does not contain $v$. Then we update the answer to $max(ans, s[i] - s[j])$, and finally update $d[v]$ to $i$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$. + ### **Python3** @@ -122,6 +130,27 @@ func maximumUniqueSubarray(nums []int) (ans int) { } ``` +### **TypeScript** + +```ts +function maximumUniqueSubarray(nums: number[]): number { + const m = Math.max(...nums); + const n = nums.length; + const s: number[] = Array.from({ length: n + 1 }, () => 0); + for (let i = 1; i <= n; ++i) { + s[i] = s[i - 1] + nums[i - 1]; + } + const d = Array.from({ length: m + 1 }, () => 0); + let [ans, j] = [0, 0]; + for (let i = 1; i <= n; ++i) { + j = Math.max(j, d[nums[i - 1]]); + ans = Math.max(ans, s[i] - s[j]); + d[nums[i - 1]] = i; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1600-1699/1695.Maximum Erasure Value/Solution.ts b/solution/1600-1699/1695.Maximum Erasure Value/Solution.ts new file mode 100644 index 0000000000000..be5a2acd32484 --- /dev/null +++ b/solution/1600-1699/1695.Maximum Erasure Value/Solution.ts @@ -0,0 +1,16 @@ +function maximumUniqueSubarray(nums: number[]): number { + const m = Math.max(...nums); + const n = nums.length; + const s: number[] = Array.from({ length: n + 1 }, () => 0); + for (let i = 1; i <= n; ++i) { + s[i] = s[i - 1] + nums[i - 1]; + } + const d = Array.from({ length: m + 1 }, () => 0); + let [ans, j] = [0, 0]; + for (let i = 1; i <= n; ++i) { + j = Math.max(j, d[nums[i - 1]]); + ans = Math.max(ans, s[i] - s[j]); + d[nums[i - 1]] = i; + } + return ans; +} diff --git a/solution/1600-1699/1696.Jump Game VI/README_EN.md b/solution/1600-1699/1696.Jump Game VI/README_EN.md index ec7d1e60f7411..bc2b29d3aff27 100644 --- a/solution/1600-1699/1696.Jump Game VI/README_EN.md +++ b/solution/1600-1699/1696.Jump Game VI/README_EN.md @@ -46,6 +46,20 @@ ## Solutions +**Solution 1: Dynamic Programming + Monotonic Queue Optimization** + +We define $f[i]$ as the maximum score when reaching index $i$. The value of $f[i]$ can be transferred from $f[j]$, where $j$ satisfies $i - k \leq j \leq i - 1$. Therefore, we can use dynamic programming to solve this problem. + +The state transition equation is: + +$$ +f[i] = \max_{j \in [i - k, i - 1]} f[j] + nums[i] +$$ + +We can use a monotonic queue to optimize the state transition equation. Specifically, we maintain a monotonically decreasing queue, which stores the index $j$, and the $f[j]$ values corresponding to the indices in the queue are monotonically decreasing. When performing state transition, we only need to take out the index $j$ at the front of the queue to get the maximum value of $f[j]$, and then update the value of $f[i]$ to $f[j] + nums[i]$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** diff --git a/solution/1600-1699/1698.Number of Distinct Substrings in a String/README_EN.md b/solution/1600-1699/1698.Number of Distinct Substrings in a String/README_EN.md index 5f9f13e86b760..7ed32b5830f4b 100644 --- a/solution/1600-1699/1698.Number of Distinct Substrings in a String/README_EN.md +++ b/solution/1600-1699/1698.Number of Distinct Substrings in a String/README_EN.md @@ -37,6 +37,24 @@ ## Solutions +**Solution 1: Brute Force Enumeration** + +Enumerate all substrings and use a hash table to record the count of different substrings. + +The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string. + +**Solution 2: String Hashing** + +**String hashing** is a method to map a string of any length to a non-negative integer, and the probability of collision is almost zero. String hashing is used to calculate the hash value of a string, which can quickly determine whether two strings are equal. + +We take a fixed value BASE, treat the string as a number in BASE radix, and assign a value greater than 0 to represent each character. Generally, the values we assign are much smaller than BASE. For example, for a string composed of lowercase letters, we can set a=1, b=2, ..., z=26. We take a fixed value MOD, calculate the remainder of the BASE radix number to MOD, and use it as the hash value of the string. + +Generally, we take BASE=131 or BASE=13331, at which point the probability of collision of the hash value is extremely low. As long as the hash values of two strings are the same, we consider the two strings to be equal. Usually, MOD is taken as 2^64. In C++, we can directly use the unsigned long long type to store this hash value. When calculating, we do not handle arithmetic overflow. When overflow occurs, it is equivalent to automatically taking the modulus of 2^64, which can avoid inefficient modulus operations. + +Except for extremely specially constructed data, the above hash algorithm is unlikely to cause collisions. In general, the above hash algorithm can appear in the standard answer of the problem. We can also take some appropriate BASE and MOD values (such as large prime numbers), perform several groups of hash operations, and only consider the original strings equal when the results are all the same, making it even more difficult to construct data that causes this hash to produce errors. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string. + ### **Python3** diff --git a/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README.md b/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README.md index 5e66b06887679..f9db8488fcd89 100644 --- a/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README.md +++ b/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README.md @@ -61,13 +61,13 @@ 我们观察发现,学生位置可调整,而三明治位置不可调整。也就是说,若前面的三明治没被拿走,则往后的所有三明治也无法被拿走。 -因此,我们先用计数器 `cnt` 统计学生喜欢的三明治种类和对应的数量。 +因此,我们先用计数器 $cnt$ 统计学生喜欢的三明治种类和对应的数量。 -然后遍历三明治,若在 `cnt` 中找不到喜欢此三明治的学生,说明后面的三明治也无法被拿走,返回当前剩余的学生数量。 +然后遍历三明治,若在 $cnt$ 中找不到喜欢此三明治的学生,说明后面的三明治也无法被拿走,返回当前剩余的学生数量。 -遍历 +遍历结束。,说明所有学生都有三明治吃,返回 $0$。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为三明治数量。 +时间复杂度 $O(n)$,其中 $n$ 为三明治数量。空间复杂度 $O(1)$。 diff --git a/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README_EN.md b/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README_EN.md index b2ab629f7074d..187d84453332f 100644 --- a/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README_EN.md +++ b/solution/1700-1799/1700.Number of Students Unable to Eat Lunch/README_EN.md @@ -54,6 +54,18 @@ Hence all students are able to eat. ## Solutions +**Solution 1: Counting** + +We observe that the positions of the students can be adjusted, but the positions of the sandwiches cannot be adjusted. That is to say, if the sandwich in front is not taken, then all the sandwiches behind cannot be taken. + +Therefore, we first use a counter $cnt$ to count the types of sandwiches that students like and their corresponding quantities. + +Then we traverse the sandwiches. If we cannot find a student who likes this sandwich in $cnt$, it means that the sandwiches behind cannot be taken, and we return the current number of remaining students. + +If the traversal is over, it means that all students have sandwiches to eat, and we return $0$. + +The time complexity is $O(n)$, where $n$ is the number of sandwiches. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1700-1799/1701.Average Waiting Time/README.md b/solution/1700-1799/1701.Average Waiting Time/README.md index 3ac16e422a1bd..c7c6d27c2c5c9 100644 --- a/solution/1700-1799/1701.Average Waiting Time/README.md +++ b/solution/1700-1799/1701.Average Waiting Time/README.md @@ -64,11 +64,11 @@ 遍历顾客数组 `customers`,对于每个顾客: -如果当前时间 `t` 小于等于顾客的到达时间 `customers[i][0]`,说明厨师没有在做菜,那么厨师可以立即开始做菜,做完这道菜的时间为 `t = customers[i][0] + customers[i][1]`,顾客的等待时间为 `customers[i][1]`。 +如果当前时间 `t` 小于等于顾客的到达时间 `customers[i][0]`,说明厨师没有在做菜,那么厨师可以立即开始做菜,做完这道菜的时间为 $t = customers[i][0] + customers[i][1]$,顾客的等待时间为 `customers[i][1]`。 -否则,说明厨师正在做菜,那么顾客需要等待厨师做完此前的菜,才能开始做自己的菜,做完这道菜的时间为 `t = t + customers[i][1]`,顾客的等待时间为 `t - customers[i][0]`。 +否则,说明厨师正在做菜,那么顾客需要等待厨师做完此前的菜,才能开始做自己的菜,做完这道菜的时间为 $t = t + customers[i][1]$,顾客的等待时间为 $t - customers[i][0]$。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为顾客数组 `customers` 的长度。 +时间复杂度 $O(n)$,其中 $n$ 为顾客数组 `customers` 的长度。空间复杂度 $O(1)$。 diff --git a/solution/1700-1799/1701.Average Waiting Time/README_EN.md b/solution/1700-1799/1701.Average Waiting Time/README_EN.md index 7501ea22b43c6..42fc8327724e6 100644 --- a/solution/1700-1799/1701.Average Waiting Time/README_EN.md +++ b/solution/1700-1799/1701.Average Waiting Time/README_EN.md @@ -52,6 +52,18 @@ So the average waiting time = (2 + 6 + 4 + 1) / 4 = 3.25. ## Solutions +**Solution 1: Simulation** + +We use a variable `tot` to record the total waiting time of the customers, and a variable `t` to record the time when each customer's order is completed. The initial values of both are $0$. + +We traverse the customer array `customers`. For each customer: + +If the current time `t` is less than or equal to the customer's arrival time `customers[i][0]`, it means that the chef is not cooking, so the chef can start cooking immediately. The time to complete this dish is $t = customers[i][0] + customers[i][1]$, and the customer's waiting time is `customers[i][1]`. + +Otherwise, it means that the chef is cooking, so the customer needs to wait for the chef to finish the previous dishes before starting to cook their own dishes. The time to complete this dish is $t = t + customers[i][1]$, and the customer's waiting time is $t - customers[i][0]$. + +The time complexity is $O(n)$, where $n$ is the length of the customer array `customers`. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1700-1799/1702.Maximum Binary String After Change/README.md b/solution/1700-1799/1702.Maximum Binary String After Change/README.md index d5a82ec6fde05..bcbf3be939470 100644 --- a/solution/1700-1799/1702.Maximum Binary String After Change/README.md +++ b/solution/1700-1799/1702.Maximum Binary String After Change/README.md @@ -65,7 +65,7 @@ 因此,要想得到最大的二进制串,我们应该把所有不在开头的 $1$ 移动到字符串末尾,使得字符串变为 `111..11...00..11` 的形式,然后借助操作 1 把中间的 `000..00` 变为 `111..10`。这样我们最终可以得到一个最多包含一个 $0$ 的二进制字符串,这个字符串就是我们要求的最大二进制串。 -时间复杂度 $O(n)$,忽略答案的空间消耗,空间复杂度 $O(1)$。其中 $n$ 为字符串 `binary` 的长度。 +时间复杂度 $O(n)$,其中 $n$ 为字符串 `binary` 的长度。忽略答案的空间消耗,空间复杂度 $O(1)$。 diff --git a/solution/1700-1799/1702.Maximum Binary String After Change/README_EN.md b/solution/1700-1799/1702.Maximum Binary String After Change/README_EN.md index fe69e79ff1131..6420fbabbf7a6 100644 --- a/solution/1700-1799/1702.Maximum Binary String After Change/README_EN.md +++ b/solution/1700-1799/1702.Maximum Binary String After Change/README_EN.md @@ -53,6 +53,14 @@ ## Solutions +**Solution 1: Quick Thinking** + +We observe that operation 2 can move all $1$s to the end of the string, and operation 1 can change all `0000..000` strings to `111..110`. + +Therefore, to get the maximum binary string, we should move all $1$s that are not at the beginning to the end of the string, making the string in the form of `111..11...00..11`, and then use operation 1 to change the middle `000..00` to `111..10`. In this way, we can finally get a binary string that contains at most one $0$, which is the maximum binary string we are looking for. + +The time complexity is $O(n)$, where $n$ is the length of the string `binary`. Ignoring the space consumption of the answer, the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README.md b/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README.md index e7305f0d93cee..e7ff6870f5b6b 100644 --- a/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README.md +++ b/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README.md @@ -49,13 +49,13 @@ **方法一:前缀和 + 中位数枚举** -我们可以将数组 `nums` 中的 `1` 的下标存入数组 `arr` 中。接下来,我们预处理数组 `arr` 的前缀和数组 `s`,其中 `s[i]` 表示数组 `arr` 中前 $i$ 个元素的和。 +我们可以将数组 $nums$ 中的 $1$ 的下标存入数组 $arr$ 中。接下来,我们预处理数组 $arr$ 的前缀和数组 $s$,其中 $s[i]$ 表示数组 $arr$ 中前 $i$ 个元素的和。 对于长度为 $k$ 的子数组,左侧(包含中位数)的元素个数 $x=\frac{k+1}{2}$,右侧的元素个数为 $y=k-x$。 -我们枚举中位数的下标 $i$,其中 $x-1\leq i\leq len(arr)-y$,那么左侧数组的前缀和 $ls=s[i+1]-s[i+1-x]$,右侧数组的前缀和 $rs=s[i+1+y]-s[i+1]$。当前中位数在 `nums` 中的下标为 $j=arr[i]$,将左侧 $x$ 个元素移动到 $[j-x+1,..j]$ 所需要的操作次数为 $a=(j+j-x+1)\times\frac{x}{2}-ls$,将右侧 $y$ 个元素移动到 $[j+1,..j+y]$ 所需要的操作次数为 $b=rs-(j+1+j+y)\times\frac{y}{2}$,那么总的操作次数为 $a+b$,我们取所有总的操作次数的最小值即可。 +我们枚举中位数的下标 $i$,其中 $x-1\leq i\leq len(arr)-y$,那么左侧数组的前缀和 $ls=s[i+1]-s[i+1-x]$,右侧数组的前缀和 $rs=s[i+1+y]-s[i+1]$。当前中位数在 $nums$ 中的下标为 $j=arr[i]$,将左侧 $x$ 个元素移动到 $[j-x+1,..j]$ 所需要的操作次数为 $a=(j+j-x+1)\times\frac{x}{2}-ls$,将右侧 $y$ 个元素移动到 $[j+1,..j+y]$ 所需要的操作次数为 $b=rs-(j+1+j+y)\times\frac{y}{2}$,那么总的操作次数为 $a+b$,我们取所有总的操作次数的最小值即可。 -时间复杂度 $O(n)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别为数组 `nums` 的长度以及数组 `nums` 中 `1` 的个数。 +时间复杂度 $O(n)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别为数组 $nums$ 的长度以及数组 $nums$ 中 $1$ 的个数。 diff --git a/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README_EN.md b/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README_EN.md index aa408a7c4ac46..1f4d8e981281c 100644 --- a/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README_EN.md +++ b/solution/1700-1799/1703.Minimum Adjacent Swaps for K Consecutive Ones/README_EN.md @@ -44,6 +44,16 @@ ## Solutions +**Solution 1: Prefix Sum + Median Enumeration** + +We can store the indices of $1$s in the array $nums$ into an array $arr$. Next, we preprocess the prefix sum array $s$ of the array $arr$, where $s[i]$ represents the sum of the first $i$ elements in the array $arr$. + +For a subarray of length $k$, the number of elements on the left (including the median) is $x=\frac{k+1}{2}$, and the number of elements on the right is $y=k-x$. + +We enumerate the index $i$ of the median, where $x-1\leq i\leq len(arr)-y$. The prefix sum of the left array is $ls=s[i+1]-s[i+1-x]$, and the prefix sum of the right array is $rs=s[i+1+y]-s[i+1]$. The current median index in $nums$ is $j=arr[i]$. The number of operations required to move the left $x$ elements to $[j-x+1,..j]$ is $a=(j+j-x+1)\times\frac{x}{2}-ls$, and the number of operations required to move the right $y$ elements to $[j+1,..j+y]$ is $b=rs-(j+1+j+y)\times\frac{y}{2}$. The total number of operations is $a+b$, and we take the minimum of all total operation counts. + +The time complexity is $O(n)$, and the space complexity is $O(m)$. Here, $n$ and $m$ are the length of the array $nums$ and the number of $1$s in the array $nums$, respectively. + ### **Python3** diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md b/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md index 9e23c1c70a8bf..47d29a1e1fa28 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md @@ -49,7 +49,7 @@ 遍历字符串,若字符串前半段的元音个数等于后半段的元音个数,则返回 `true`,否则返回 `false`。 -时间复杂度 $O(n)$,其中 $n$ 为字符串的长度。 +时间复杂度 $O(n)$,其中 $n$ 为字符串的长度。空间复杂度 $O(C)$,其中 $C$ 为元音字母的个数。 diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md b/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md index 9e92c178593dc..9af178b3e83a4 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md @@ -39,6 +39,12 @@ Notice that the vowel o is counted twice. ## Solutions +**Solution 1: Counting** + +Traverse the string. If the number of vowels in the first half of the string is equal to the number of vowels in the second half, return `true`. Otherwise, return `false`. + +The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(C)$, where $C$ is the number of vowel characters. + ### **Python3** diff --git a/solution/1700-1799/1705.Maximum Number of Eaten Apples/README_EN.md b/solution/1700-1799/1705.Maximum Number of Eaten Apples/README_EN.md index e91ef1c69c9e5..c9564d53c0b3d 100644 --- a/solution/1700-1799/1705.Maximum Number of Eaten Apples/README_EN.md +++ b/solution/1700-1799/1705.Maximum Number of Eaten Apples/README_EN.md @@ -46,6 +46,14 @@ ## Solutions +**Solution 1: Greedy + Priority Queue** + +We can greedily choose the apple that is most likely to rot among the unrotten apples, so that we can eat as many apples as possible. + +Therefore, we can use a priority queue (min heap) to store the rotting time of the apples and the corresponding number of apples. Each time we take out the apple with the smallest rotting time from the priority queue, then reduce its quantity by one. If the quantity of the apple is not zero after reduction, we put it back into the priority queue. If the apple has rotted, we pop it out from the priority queue. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array `apples` or `days`. + ### **Python3** diff --git a/solution/1700-1799/1708.Largest Subarray Length K/README.md b/solution/1700-1799/1708.Largest Subarray Length K/README.md index efa921d0b8437..64a96d4848363 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/README.md +++ b/solution/1700-1799/1708.Largest Subarray Length K/README.md @@ -65,7 +65,7 @@ 数组中所有整数都不同,我们可以先在 $[0,..n-k]$ 范围内找到最大的元素的下标,然后从该下标开始取 $k$ 个元素即可。 -时间复杂度 $O(n)$,忽略答案的空间消耗,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。 +时间复杂度 $O(n)$,其中 $n$ 为数组的长度。忽略答案的空间消耗,空间复杂度 $O(1)$。 @@ -76,8 +76,7 @@ ```python class Solution: def largestSubarray(self, nums: List[int], k: int) -> List[int]: - mx = max(nums[: len(nums) - k + 1]) - i = nums.index(mx) + i = nums.index(max(nums[: len(nums) - k + 1])) return nums[i : i + k] ``` @@ -88,18 +87,13 @@ class Solution: ```java class Solution { public int[] largestSubarray(int[] nums, int k) { - int i = 0, mx = 0; - for (int j = 0; j < nums.length - k + 1; ++j) { - if (mx < nums[j]) { - mx = nums[j]; - i = j; + int j = 0; + for (int i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; } } - int[] ans = new int[k]; - for (int j = 0; j < k; ++j) { - ans[j] = nums[i + j]; - } - return ans; + return Arrays.copyOfRange(nums, j, j + k); } } ``` @@ -110,48 +104,53 @@ class Solution { class Solution { public: vector largestSubarray(vector& nums, int k) { - auto pos = max_element(nums.begin(), nums.begin() + nums.size() - k + 1); - return {pos, pos + k}; + auto i = max_element(nums.begin(), nums.end() - k + 1); + return {i, i + k}; } }; ``` -### **Rust** +### **Go** -```rust -impl Solution { - #[allow(dead_code)] - pub fn largest_subarray(nums: Vec, k: i32) -> Vec { - let mut ret_vec = vec![i32::MIN]; - let n = nums.len(); +```go +func largestSubarray(nums []int, k int) []int { + j := 0 + for i := 1; i < len(nums)-k+1; i++ { + if nums[j] < nums[i] { + j = i + } + } + return nums[j : j+k] +} +``` - if n == (k as usize) { - return nums; - } +### **TypeScript** - for i in 0..=n - (k as usize) { - if nums[i] > ret_vec[0] { - ret_vec = nums[i..i + (k as usize)].to_vec(); - } +```ts +function largestSubarray(nums: number[], k: number): number[] { + let j = 0; + for (let i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; } - - ret_vec } + return nums.slice(j, j + k); } ``` -### **Go** +### **Rust** -```go -func largestSubarray(nums []int, k int) []int { - i, mx := 0, 0 - for j := 0; j < len(nums)-k+1; j++ { - if mx < nums[j] { - mx = nums[j] - i = j - } - } - return nums[i : i+k] +```rust +impl Solution { + pub fn largest_subarray(nums: Vec, k: i32) -> Vec { + let mut j = 0; + for i in 1..=nums.len() - (k as usize) { + if nums[i] > nums[j] { + j = i; + } + } + nums[j..j + (k as usize)].to_vec() + } } ``` diff --git a/solution/1700-1799/1708.Largest Subarray Length K/README_EN.md b/solution/1700-1799/1708.Largest Subarray Length K/README_EN.md index 3814ee762b5ea..64c866b199478 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/README_EN.md +++ b/solution/1700-1799/1708.Largest Subarray Length K/README_EN.md @@ -55,6 +55,12 @@ Of these, [4,5,2,3] is the largest. ## Solutions +**Solution 1: Simulation** + +All integers in the array are distinct, so we can first find the index of the maximum element in the range $[0,..n-k]$, and then take $k$ elements starting from this index. + +The time complexity is $O(n)$, where $n$ is the length of the array. Ignoring the space consumption of the answer, the space complexity is $O(1)$. + ### **Python3** @@ -62,8 +68,7 @@ Of these, [4,5,2,3] is the largest. ```python class Solution: def largestSubarray(self, nums: List[int], k: int) -> List[int]: - mx = max(nums[: len(nums) - k + 1]) - i = nums.index(mx) + i = nums.index(max(nums[: len(nums) - k + 1])) return nums[i : i + k] ``` @@ -72,18 +77,13 @@ class Solution: ```java class Solution { public int[] largestSubarray(int[] nums, int k) { - int i = 0, mx = 0; - for (int j = 0; j < nums.length - k + 1; ++j) { - if (mx < nums[j]) { - mx = nums[j]; - i = j; + int j = 0; + for (int i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; } } - int[] ans = new int[k]; - for (int j = 0; j < k; ++j) { - ans[j] = nums[i + j]; - } - return ans; + return Arrays.copyOfRange(nums, j, j + k); } } ``` @@ -94,48 +94,53 @@ class Solution { class Solution { public: vector largestSubarray(vector& nums, int k) { - auto pos = max_element(nums.begin(), nums.begin() + nums.size() - k + 1); - return {pos, pos + k}; + auto i = max_element(nums.begin(), nums.end() - k + 1); + return {i, i + k}; } }; ``` -### **Rust** +### **Go** -```rust -impl Solution { - #[allow(dead_code)] - pub fn largest_subarray(nums: Vec, k: i32) -> Vec { - let mut ret_vec = vec![i32::MIN]; - let n = nums.len(); +```go +func largestSubarray(nums []int, k int) []int { + j := 0 + for i := 1; i < len(nums)-k+1; i++ { + if nums[j] < nums[i] { + j = i + } + } + return nums[j : j+k] +} +``` - if n == (k as usize) { - return nums; - } +### **TypeScript** - for i in 0..=n - (k as usize) { - if nums[i] > ret_vec[0] { - ret_vec = nums[i..i + (k as usize)].to_vec(); - } +```ts +function largestSubarray(nums: number[], k: number): number[] { + let j = 0; + for (let i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; } - - ret_vec } + return nums.slice(j, j + k); } ``` -### **Go** +### **Rust** -```go -func largestSubarray(nums []int, k int) []int { - i, mx := 0, 0 - for j := 0; j < len(nums)-k+1; j++ { - if mx < nums[j] { - mx = nums[j] - i = j - } - } - return nums[i : i+k] +```rust +impl Solution { + pub fn largest_subarray(nums: Vec, k: i32) -> Vec { + let mut j = 0; + for i in 1..=nums.len() - (k as usize) { + if nums[i] > nums[j] { + j = i; + } + } + nums[j..j + (k as usize)].to_vec() + } } ``` diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.cpp b/solution/1700-1799/1708.Largest Subarray Length K/Solution.cpp index 1c2c591f6a863..2d3ab1aa0b9ea 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/Solution.cpp +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.cpp @@ -1,7 +1,7 @@ -class Solution { -public: - vector largestSubarray(vector& nums, int k) { - auto pos = max_element(nums.begin(), nums.begin() + nums.size() - k + 1); - return {pos, pos + k}; - } +class Solution { +public: + vector largestSubarray(vector& nums, int k) { + auto i = max_element(nums.begin(), nums.end() - k + 1); + return {i, i + k}; + } }; \ No newline at end of file diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.go b/solution/1700-1799/1708.Largest Subarray Length K/Solution.go index 004ebb93c321d..58c534de993ac 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/Solution.go +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.go @@ -1,10 +1,9 @@ func largestSubarray(nums []int, k int) []int { - i, mx := 0, 0 - for j := 0; j < len(nums)-k+1; j++ { - if mx < nums[j] { - mx = nums[j] - i = j + j := 0 + for i := 1; i < len(nums)-k+1; i++ { + if nums[j] < nums[i] { + j = i } } - return nums[i : i+k] + return nums[j : j+k] } \ No newline at end of file diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.java b/solution/1700-1799/1708.Largest Subarray Length K/Solution.java index 57d2ba7f4f73e..ae998c3c268d9 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/Solution.java +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.java @@ -1,16 +1,11 @@ -class Solution { - public int[] largestSubarray(int[] nums, int k) { - int i = 0, mx = 0; - for (int j = 0; j < nums.length - k + 1; ++j) { - if (mx < nums[j]) { - mx = nums[j]; - i = j; - } - } - int[] ans = new int[k]; - for (int j = 0; j < k; ++j) { - ans[j] = nums[i + j]; - } - return ans; - } +class Solution { + public int[] largestSubarray(int[] nums, int k) { + int j = 0; + for (int i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; + } + } + return Arrays.copyOfRange(nums, j, j + k); + } } \ No newline at end of file diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.py b/solution/1700-1799/1708.Largest Subarray Length K/Solution.py index 98d5e4441b270..dacfa4d0921a0 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/Solution.py +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.py @@ -1,5 +1,4 @@ -class Solution: - def largestSubarray(self, nums: List[int], k: int) -> List[int]: - mx = max(nums[: len(nums) - k + 1]) - i = nums.index(mx) - return nums[i : i + k] +class Solution: + def largestSubarray(self, nums: List[int], k: int) -> List[int]: + i = nums.index(max(nums[: len(nums) - k + 1])) + return nums[i : i + k] diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.rs b/solution/1700-1799/1708.Largest Subarray Length K/Solution.rs index 3f1dc186d1591..f809881018736 100644 --- a/solution/1700-1799/1708.Largest Subarray Length K/Solution.rs +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.rs @@ -1,19 +1,11 @@ impl Solution { - #[allow(dead_code)] pub fn largest_subarray(nums: Vec, k: i32) -> Vec { - let mut ret_vec = vec![i32::MIN]; - let n = nums.len(); - - if n == (k as usize) { - return nums; - } - - for i in 0..=n - (k as usize) { - if nums[i] > ret_vec[0] { - ret_vec = nums[i..i + (k as usize)].to_vec(); + let mut j = 0; + for i in 1..=nums.len() - (k as usize) { + if nums[i] > nums[j] { + j = i; } } - - ret_vec + nums[j..j + (k as usize)].to_vec() } } diff --git a/solution/1700-1799/1708.Largest Subarray Length K/Solution.ts b/solution/1700-1799/1708.Largest Subarray Length K/Solution.ts new file mode 100644 index 0000000000000..e3dffdebf499c --- /dev/null +++ b/solution/1700-1799/1708.Largest Subarray Length K/Solution.ts @@ -0,0 +1,9 @@ +function largestSubarray(nums: number[], k: number): number[] { + let j = 0; + for (let i = 1; i < nums.length - k + 1; ++i) { + if (nums[j] < nums[i]) { + j = i; + } + } + return nums.slice(j, j + k); +} diff --git a/solution/1700-1799/1710.Maximum Units on a Truck/README.md b/solution/1700-1799/1710.Maximum Units on a Truck/README.md index 4f35d9db27274..882ffb005a6e2 100644 --- a/solution/1700-1799/1710.Maximum Units on a Truck/README.md +++ b/solution/1700-1799/1710.Maximum Units on a Truck/README.md @@ -58,7 +58,7 @@ 然后从前往后遍历 `boxTypes`,选择最多 `truckSize` 个箱子,累加单元数。 -时间复杂度 $O(n\times \log n)$,其中 $n$ 表示二维数组 `boxTypes` 的长度。 +时间复杂度 $O(n \times \log n)$,其中 $n$ 表示二维数组 `boxTypes` 的长度。 **方法二:计数排序** diff --git a/solution/1700-1799/1710.Maximum Units on a Truck/README_EN.md b/solution/1700-1799/1710.Maximum Units on a Truck/README_EN.md index 95015eaebef29..3673d77c44f09 100644 --- a/solution/1700-1799/1710.Maximum Units on a Truck/README_EN.md +++ b/solution/1700-1799/1710.Maximum Units on a Truck/README_EN.md @@ -47,6 +47,22 @@ The total number of units will be = (1 * 3) + (2 * 2) + (1 * 1) = 8. ## Solutions +**Solution 1: Greedy + Sorting** + +According to the problem, we should choose as many units as possible. Therefore, we first sort `boxTypes` in descending order of the number of units. + +Then we traverse `boxTypes` from front to back, choose up to `truckSize` boxes, and accumulate the number of units. + +The time complexity is $O(n \times \log n)$, where $n$ is the length of the two-dimensional array `boxTypes`. + +**Solution 2: Counting Sort** + +We can also use the idea of counting sort, create an array $cnt$ of length $1001$, where $cnt[b]$ represents the number of boxes with $b$ units. + +Then starting from the box with the maximum number of units, choose up to `truckSize` boxes, and accumulate the number of units. + +The time complexity is $O(M)$, where $M$ is the maximum number of units. In this problem, $M=1000$. + ### **Python3** diff --git a/solution/1700-1799/1711.Count Good Meals/README_EN.md b/solution/1700-1799/1711.Count Good Meals/README_EN.md index 5fef18c76c254..453412002730c 100644 --- a/solution/1700-1799/1711.Count Good Meals/README_EN.md +++ b/solution/1700-1799/1711.Count Good Meals/README_EN.md @@ -39,6 +39,26 @@ Their respective sums are 4, 8, 8, and 16, all of which are powers of 2. ## Solutions +**Solution 1: Hash Table + Enumeration of Powers of Two** + +According to the problem, we need to count the number of combinations in the array where the sum of two numbers is a power of $2$. Directly enumerating all combinations has a time complexity of $O(n^2)$, which will definitely time out. + +We can traverse the array and use a hash table $cnt$ to maintain the number of occurrences of each element $d$ in the array. + +For each element, we enumerate the powers of two $s$ as the sum of two numbers from small to large, and add the number of occurrences of $s - d$ in the hash table to the answer. Then increase the number of occurrences of the current element $d$ by one. + +After the traversal ends, return the answer. + +The time complexity is $O(n \times \log M)$, where $n$ is the length of the array `deliciousness`, and $M$ is the upper limit of the elements. For this problem, the upper limit $M=2^{20}$. + +We can also use a hash table $cnt$ to count the number of occurrences of each element in the array first. + +Then enumerate the powers of two $s$ as the sum of two numbers from small to large. For each $s$, traverse each key-value pair $(a, m)$ in the hash table. If $s - a$ is also in the hash table, and $s - a \neq a$, then add $m \times cnt[s - a]$ to the answer; if $s - a = a$, then add $m \times (m - 1)$ to the answer. + +Finally, divide the answer by $2$, modulo $10^9 + 7$, and return. + +The time complexity is the same as the method above. + ### **Python3** diff --git a/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README.md b/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README.md index 181a3278bbaeb..469a380f2b00b 100644 --- a/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README.md +++ b/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README.md @@ -57,9 +57,9 @@ **方法一:前缀和 + 二分查找** -我们先预处理出数组 `nums` 的前缀和数组 $s$,其中 $s[i]$ 表述数组 `nums` 前 $i+1$ 个元素之和。 +我们先预处理出数组 $nums$ 的前缀和数组 $s$,其中 $s[i]$ 表述数组 $nums$ 前 $i+1$ 个元素之和。 -由于数组 `nums` 的元素都是非负整数,因此前缀和数组 $s$ 是一个单调递增数组。 +由于数组 $nums$ 的元素都是非负整数,因此前缀和数组 $s$ 是一个单调递增数组。 我们在 $[0,..n-2)$ 的范围内枚举 `left` 子数组所能到达的下标 $i$,然后利用前缀和数组单调递增的特性,通过二分查找的方式找到 `mid` 子数组分割的合理范围,记为 $[j, k)$,累加方案数 $k-j$。 @@ -67,7 +67,7 @@ 最后,将方案数对 $10^9+7$ 取模后返回即可。 -时间复杂度 $O(n\times \log n)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n \times \log n)$。其中 $n$ 为数组 $nums$ 的长度。 diff --git a/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README_EN.md b/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README_EN.md index 02a94d888269e..7ce95c4fb4d33 100644 --- a/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README_EN.md +++ b/solution/1700-1799/1712.Ways to Split Array Into Three Subarrays/README_EN.md @@ -49,6 +49,20 @@ ## Solutions +**Solution 1: Prefix Sum + Binary Search** + +First, we preprocess the prefix sum array $s$ of the array $nums$, where $s[i]$ represents the sum of the first $i+1$ elements of the array $nums$. + +Since all elements of the array $nums$ are non-negative integers, the prefix sum array $s$ is a monotonically increasing array. + +We enumerate the index $i$ that the `left` subarray can reach in the range $[0,..n-2)$, and then use the monotonically increasing characteristic of the prefix sum array to find the reasonable range of the `mid` subarray split by binary search, denoted as $[j, k)$, and accumulate the number of schemes $k-j$. + +In the binary search details, the subarray split must satisfy $s[j] \geq s[i]$ and $s[n - 1] - s[k] \geq s[k] - s[i]$. That is, $s[j] \geq s[i]$ and $s[k] \leq \frac{s[n - 1] + s[i]}{2}$. + +Finally, return the number of schemes modulo $10^9+7$. + +The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $nums$. + ### **Python3** diff --git a/solution/1700-1799/1714.Sum Of Special Evenly-Spaced Elements In Array/README_EN.md b/solution/1700-1799/1714.Sum Of Special Evenly-Spaced Elements In Array/README_EN.md index a3a7890588878..e1433d1b349c3 100644 --- a/solution/1700-1799/1714.Sum Of Special Evenly-Spaced Elements In Array/README_EN.md +++ b/solution/1700-1799/1714.Sum Of Special Evenly-Spaced Elements In Array/README_EN.md @@ -43,6 +43,19 @@ ## Solutions +**Solution 1: Block Decomposition** + +This problem is a typical block decomposition problem. For queries with a large step size, we can directly brute force the solution; for queries with a small step size, we can preprocess the suffix sum of each position and then directly query. + +In this problem, we limit the step size of the large step size query to $\sqrt{n}$, which can ensure that the time complexity of each query is $O(\sqrt{n})$. + +We define a two-dimensional array $suf$, where $suf[i][j]$ represents the suffix sum starting from position $j$ with a step size of $i$. Then for each query $[x, y]$, we can divide it into two cases: + +- If $y \le \sqrt{n}$, then we can directly query $suf[y][x]$; +- If $y > \sqrt{n}$, then we can directly brute force the solution. + +The time complexity is $O((n + m) \times \sqrt{n})$, and the space complexity is $O(n \times \sqrt{n})$. Here, $n$ is the length of the array, and $m$ is the number of queries. + ### **Python3** diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md index 99647ecbac9fb..d687e51498635 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md @@ -55,70 +55,13 @@ source 和 target 间的汉明距离是 2 ,二者有 2 处元素不同,在 -并查集。 +**方法一:并查集 + 哈希表** -模板 1——朴素并查集: - -```python -# 初始化,p存储每个点的父节点 -p = list(range(n)) - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - # 路径压缩 - p[x] = find(p[x]) - return p[x] - - -# 合并a和b所在的两个集合 -p[find(a)] = find(b) -``` - -模板 2——维护 size 的并查集: - -```python -# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量 -p = list(range(n)) -size = [1] * n - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - # 路径压缩 - p[x] = find(p[x]) - return p[x] +我们可以将每个下标看作一个节点,每个下标对应的元素看作节点的值,那么给定的 `allowedSwaps` 中的每个元素 `[a_i, b_i]` 就表示下标 `a_i` 和 `b_i` 之间存在一条边。因此,我们可以使用并查集来维护这些连通分量。 +在得到每个连通分量之后,我们再用二维哈希表 $cnt$ 分别统计每个连通分量中每个元素出现的次数,最后对于数组 `target` 中的每个元素,如果其在对应的连通分量中出现的次数大于 0,则将其出现次数减 1,否则将答案加 1。 -# 合并a和b所在的两个集合 -if find(a) != find(b): - size[find(b)] += size[find(a)] - p[find(a)] = find(b) -``` - -模板 3——维护到祖宗节点距离的并查集: - -```python -# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离 -p = list(range(n)) -d = [0] * n - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - t = find(p[x]) - d[x] += d[p[x]] - p[x] = t - return p[x] - - -# 合并a和b所在的两个集合 -p[find(a)] = find(b) -d[find(a)] = distance -``` +时间复杂度 $O(n \times \log n)$ 或 $O(n \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度,而 $\alpha$ 是阿克曼函数的反函数。 @@ -131,27 +74,25 @@ class Solution: def minimumHammingDistance( self, source: List[int], target: List[int], allowedSwaps: List[List[int]] ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans ``` ### **Java** @@ -165,28 +106,26 @@ class Solution { public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { int n = source.length; p = new int[n]; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; i++) { p[i] = i; } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); } - Map> mp = new HashMap<>(); + Map> cnt = new HashMap<>(); for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); } - int res = 0; + int ans = 0; for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; } } - return res; + return ans; } private int find(int x) { @@ -203,28 +142,27 @@ class Solution { ```cpp class Solution { public: - vector p; - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; + ++cnt[find(i)][source[i]]; } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; } }; ``` @@ -232,40 +170,79 @@ public: ### **Go** ```go -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) + } + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } - mp[find(i)][source[i]]++ + cnt[j][x]++ } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ } } - return res + return } +``` -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) - } - return p[x] +### **TypeScript** + +```ts +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md index 50d27fafc732f..6be207e77fa02 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md @@ -53,7 +53,13 @@ The Hamming distance of source and target is 2 as they differ in 2 positions: in ## Solutions -Union find. +**Solution 1: Union-Find + Hash Table** + +We can consider each index as a node, and the element corresponding to each index as the value of the node. Then each element `[a_i, b_i]` in the given `allowedSwaps` represents an edge between index `a_i` and `b_i`. Therefore, we can use a union-find set to maintain these connected components. + +After obtaining each connected component, we use a two-dimensional hash table $cnt$ to count the number of occurrences of each element in each connected component. Finally, for each element in the array `target`, if its occurrence count in the corresponding connected component is greater than 0, we decrease its count by 1, otherwise, we increase the answer by 1. + +The time complexity is $O(n \times \log n)$ or $O(n \times \alpha(n))$, and the space complexity is $O(n)$. Here, $n$ is the length of the array, and $\alpha$ is the inverse Ackermann function. @@ -64,27 +70,25 @@ class Solution: def minimumHammingDistance( self, source: List[int], target: List[int], allowedSwaps: List[List[int]] ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans ``` ### **Java** @@ -96,28 +100,26 @@ class Solution { public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { int n = source.length; p = new int[n]; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; i++) { p[i] = i; } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); } - Map> mp = new HashMap<>(); + Map> cnt = new HashMap<>(); for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); } - int res = 0; + int ans = 0; for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; } } - return res; + return ans; } private int find(int x) { @@ -134,28 +136,27 @@ class Solution { ```cpp class Solution { public: - vector p; - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; + ++cnt[find(i)][source[i]]; } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; } }; ``` @@ -163,40 +164,79 @@ public: ### **Go** ```go -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) + } + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } - mp[find(i)][source[i]]++ + cnt[j][x]++ } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ } } - return res + return } +``` -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) - } - return p[x] +### **TypeScript** + +```ts +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp index 1fc9aeb7ad077..9f06ac04c126a 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp @@ -1,26 +1,25 @@ -class Solution { -public: - vector p; - - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { - int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; - for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; - } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; - } +class Solution { +public: + int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { + int n = source.size(); + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; + for (int i = 0; i < n; ++i) { + ++cnt[find(i)][source[i]]; + } + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go index 0e6a2a7a417cd..162a8bf95de26 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go @@ -1,35 +1,33 @@ -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) - } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) } - mp[find(i)][source[i]]++ + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } + cnt[j][x]++ } - return res -} - -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ + } } - return p[x] + return } \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java index cc54b3d824d96..b33f5b0b1ae4e 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java @@ -1,37 +1,35 @@ -class Solution { - private int[] p; - - public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { - int n = source.length; - p = new int[n]; - for (int i = 0; i < n; ++i) { - p[i] = i; - } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); - } - Map> mp = new HashMap<>(); - for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); - } - int res = 0; - for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; - } - } - return res; - } - - private int find(int x) { - if (p[x] != x) { - p[x] = find(p[x]); - } - return p[x]; - } +class Solution { + private int[] p; + + public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { + int n = source.length; + p = new int[n]; + for (int i = 0; i < n; i++) { + p[i] = i; + } + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + Map> cnt = new HashMap<>(); + for (int i = 0; i < n; ++i) { + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; + } + } + return ans; + } + + private int find(int x) { + if (p[x] != x) { + p[x] = find(p[x]); + } + return p[x]; + } } \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py index b3b8b6ba01741..c64fba92b2783 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py @@ -1,25 +1,23 @@ -class Solution: - def minimumHammingDistance( - self, source: List[int], target: List[int], allowedSwaps: List[List[int]] - ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): - if p[x] != x: - p[x] = find(p[x]) - return p[x] - - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res +class Solution: + def minimumHammingDistance( + self, source: List[int], target: List[int], allowedSwaps: List[List[int]] + ) -> int: + def find(x: int) -> int: + if p[x] != x: + p[x] = find(p[x]) + return p[x] + + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts new file mode 100644 index 0000000000000..9ff03dcf9cc46 --- /dev/null +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts @@ -0,0 +1,36 @@ +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; +} diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md index e1eefa2c804dd..6f428b5f85ef8 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md @@ -47,6 +47,16 @@ +**方法一:一次遍历** + +我们定义一个变量 $ans$ 来记录当前最大边长的正方形的个数,定义另一个变量 $mx$ 来记录当前最大的边长。 + +遍历数组 $rectangles$,对于每个矩形 $[l, w]$,我们取 $x = \min(l, w)$,如果 $mx < x$,说明我们找到了一个更大的边长,此时我们将 $mx$ 更新为 $x$,并将 $ans$ 更新为 $1$;如果 $mx = x$,说明我们找到了一个和当前最大边长相同的边长,此时我们将 $ans$ 增加 $1$。 + +最后返回 $ans$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 为数组 $rectangles$ 的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -58,10 +68,11 @@ class Solution: def countGoodRectangles(self, rectangles: List[List[int]]) -> int: ans = mx = 0 for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: ans += 1 return ans ``` @@ -74,12 +85,12 @@ class Solution: class Solution { public int countGoodRectangles(int[][] rectangles) { int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) { + } else if (mx == x) { ++ans; } } @@ -88,25 +99,6 @@ class Solution { } ``` -### **TypeSript** - -```ts -function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; - ans = 1; - } - } - return ans; -} -``` - ### **C++** ```cpp @@ -114,13 +106,14 @@ class Solution { public: int countGoodRectangles(vector>& rectangles) { int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) + } else if (mx == x) { ++ans; + } } return ans; } @@ -130,20 +123,36 @@ public: ### **Go** ```go -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function countGoodRectangles(rectangles: number[][]): number { + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx === x) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md index 8537f74de2f28..076da9d7f7269 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md @@ -41,6 +41,16 @@ The largest possible square is of length 5, and you can get it out of 3 rectangl ## Solutions +**Solution 1: Single Pass** + +We define a variable $ans$ to record the count of squares with the current maximum side length, and another variable $mx$ to record the current maximum side length. + +We traverse the array $rectangles$. For each rectangle $[l, w]$, we take $x = \min(l, w)$. If $mx < x$, it means we have found a larger side length, so we update $mx$ to $x$ and update $ans$ to $1$. If $mx = x$, it means we have found a side length equal to the current maximum side length, so we increase $ans$ by $1$. + +Finally, we return $ans$. + +The time complexity is $O(n)$, where $n$ is the length of the array $rectangles$. The space complexity is $O(1)$. + ### **Python3** @@ -50,10 +60,11 @@ class Solution: def countGoodRectangles(self, rectangles: List[List[int]]) -> int: ans = mx = 0 for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: ans += 1 return ans ``` @@ -64,12 +75,12 @@ class Solution: class Solution { public int countGoodRectangles(int[][] rectangles) { int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) { + } else if (mx == x) { ++ans; } } @@ -78,25 +89,6 @@ class Solution { } ``` -### **TypeScript** - -```ts -function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; - ans = 1; - } - } - return ans; -} -``` - ### **C++** ```cpp @@ -104,13 +96,14 @@ class Solution { public: int countGoodRectangles(vector>& rectangles) { int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) + } else if (mx == x) { ++ans; + } } return ans; } @@ -120,20 +113,36 @@ public: ### **Go** ```go -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function countGoodRectangles(rectangles: number[][]): number { + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx === x) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp index 8644b9b962724..167ee2325e5b9 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp @@ -1,15 +1,16 @@ -class Solution { -public: - int countGoodRectangles(vector>& rectangles) { - int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; - ans = 1; - } else if (mx == t) - ++ans; - } - return ans; - } +class Solution { +public: + int countGoodRectangles(vector>& rectangles) { + int ans = 0, mx = 0; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx == x) { + ++ans; + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go index c65572904e834..13cbea30b0d00 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go @@ -1,15 +1,13 @@ -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return } \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java index e066b57fb7431..eda3cedcc5ee7 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java @@ -1,15 +1,15 @@ -class Solution { - public int countGoodRectangles(int[][] rectangles) { - int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; - ans = 1; - } else if (mx == t) { - ++ans; - } - } - return ans; - } +class Solution { + public int countGoodRectangles(int[][] rectangles) { + int ans = 0, mx = 0; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx == x) { + ++ans; + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py index 8a1ee4eb1b232..bf0b05847b281 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py @@ -1,10 +1,11 @@ -class Solution: - def countGoodRectangles(self, rectangles: List[List[int]]) -> int: - ans = mx = 0 - for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: - ans += 1 - return ans +class Solution: + def countGoodRectangles(self, rectangles: List[List[int]]) -> int: + ans = mx = 0 + for l, w in rectangles: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: + ans += 1 + return ans diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts index f5111a630c851..46ee5dcbbd6f5 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts @@ -1,13 +1,12 @@ function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; ans = 1; + } else if (mx === x) { + ++ans; } } return ans; diff --git a/solution/1700-1799/1732.Find the Highest Altitude/README_EN.md b/solution/1700-1799/1732.Find the Highest Altitude/README_EN.md index 97eb331b25934..a6176f7dee71b 100644 --- a/solution/1700-1799/1732.Find the Highest Altitude/README_EN.md +++ b/solution/1700-1799/1732.Find the Highest Altitude/README_EN.md @@ -36,6 +36,26 @@ ## Solutions +**Solution 1: Prefix Sum (Difference Array)** + +We assume the altitude of each point is $h_i$. Since $gain[i]$ represents the altitude difference between the $i$th point and the $(i + 1)$th point, we have $gain[i] = h_{i + 1} - h_i$. Therefore: + +$$ +\sum_{i = 0}^{n-1} gain[i] = h_1 - h_0 + h_2 - h_1 + \cdots + h_n - h_{n - 1} = h_n - h_0 = h_n +$$ + +which implies: + +$$ +h_{i+1} = \sum_{j = 0}^{i} gain[j] +$$ + +We can see that the altitude of each point can be calculated through the prefix sum. Therefore, we only need to traverse the array once, find the maximum value of the prefix sum, which is the highest altitude. + +> In fact, the $gain$ array in the problem is a difference array. The prefix sum of the difference array gives the original altitude array. Then find the maximum value of the original altitude array. + +The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array `gain`. + ### **Python3** diff --git a/solution/1700-1799/1734.Decode XORed Permutation/README_EN.md b/solution/1700-1799/1734.Decode XORed Permutation/README_EN.md index c51b9acf5ce5d..ffd79009ff24a 100644 --- a/solution/1700-1799/1734.Decode XORed Permutation/README_EN.md +++ b/solution/1700-1799/1734.Decode XORed Permutation/README_EN.md @@ -37,6 +37,12 @@ ## Solutions +**Solution 1: Bitwise Operation** + +We notice that the array $perm$ is a permutation of the first $n$ positive integers, so the XOR of all elements in $perm$ is $1 \oplus 2 \oplus \cdots \oplus n$, denoted as $a$. And $encode[i]=perm[i] \oplus perm[i+1]$, if we denote the XOR of all elements $encode[0],encode[2],\cdots,encode[n-3]$ as $b$, then $perm[n-1]=a \oplus b$. Knowing the last element of $perm$, we can find all elements of $perm$ by traversing the array $encode$ in reverse order. + +The time complexity is $O(n)$, where $n$ is the length of the array $perm$. Ignoring the space consumption of the answer, the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1700-1799/1735.Count Ways to Make Array With Product/README_EN.md b/solution/1700-1799/1735.Count Ways to Make Array With Product/README_EN.md index 6595be2308a49..692d66ed09b34 100644 --- a/solution/1700-1799/1735.Count Ways to Make Array With Product/README_EN.md +++ b/solution/1700-1799/1735.Count Ways to Make Array With Product/README_EN.md @@ -37,6 +37,22 @@ ## Solutions +**Solution 1: Prime Factorization + Combinatorial Mathematics** + +We can perform prime factorization on $k$, i.e., $k = p_1^{x_1} \times p_2^{x_2} \times \cdots \times p_m^{x_m}$, where $p_i$ is a prime number, and $x_i$ is the exponent of $p_i$. The problem is equivalent to: placing $x_1$ $p_1$s, $x_2$ $p_2$s, $\cdots$, $x_m$ $p_m$s into $n$ positions respectively, where a single position can be empty. The question is how many schemes are there. + +According to combinatorial mathematics, there are two cases when we put $x$ balls into $n$ boxes: + +If the box cannot be empty, the number of schemes is $C_{x-1}^{n-1}$. This is using the partition method, i.e., there are a total of $x$ balls, and we insert $n-1$ partitions at $x-1$ positions, thereby dividing the $x$ balls into $n$ groups. + +If the box can be empty, we can add $n$ virtual balls, and then use the partition method, i.e., there are a total of $x+n$ balls, and we insert $n-1$ partitions at $x+n-1$ positions, thereby dividing the actual $x$ balls into $n$ groups and allowing the box to be empty. Therefore, the number of schemes is $C_{x+n-1}^{n-1}$. + +Therefore, for each query $queries[i]$, we can first perform prime factorization on $k$ to get the exponents $x_1, x_2, \cdots, x_m$, then calculate $C_{x_1+n-1}^{n-1}, C_{x_2+n-1}^{n-1}, \cdots, C_{x_m+n-1}^{n-1}$, and finally multiply all the scheme numbers. + +So, the problem is transformed into how to quickly calculate $C_m^n$. According to the formula $C_m^n = \frac{m!}{n!(m-n)!}$, we can pre-process $m!$, and then use the inverse element to quickly calculate $C_m^n$. + +The time complexity is $O(K \times \log \log K + N + m \times \log K)$, and the space complexity is $O(N)$. + ### **Python3** diff --git a/solution/1700-1799/1736.Latest Time by Replacing Hidden Digits/README_EN.md b/solution/1700-1799/1736.Latest Time by Replacing Hidden Digits/README_EN.md index 1d657c3de3856..10b46b009f4c1 100644 --- a/solution/1700-1799/1736.Latest Time by Replacing Hidden Digits/README_EN.md +++ b/solution/1700-1799/1736.Latest Time by Replacing Hidden Digits/README_EN.md @@ -43,6 +43,17 @@ ## Solutions +**Solution 1: Greedy** + +We process each digit of the string in order, following these rules: + +1. First digit: If the value of the second digit is determined and falls within the range $[4, 9]$, then the first digit can only be $1$. Otherwise, the first digit can be up to $2$. +1. Second digit: If the value of the first digit is determined and is $2$, then the second digit can be up to $3$. Otherwise, the second digit can be up to $9$. +1. Third digit: The third digit can be up to $5$. +1. Fourth digit: The fourth digit can be up to $9$. + +The time complexity is $O(1)$, and the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/1700-1799/1737.Change Minimum Characters to Satisfy One of Three Conditions/README_EN.md b/solution/1700-1799/1737.Change Minimum Characters to Satisfy One of Three Conditions/README_EN.md index 963dbfe40438d..db9f938f78ccb 100644 --- a/solution/1700-1799/1737.Change Minimum Characters to Satisfy One of Three Conditions/README_EN.md +++ b/solution/1700-1799/1737.Change Minimum Characters to Satisfy One of Three Conditions/README_EN.md @@ -47,7 +47,17 @@ The best way was done in 2 operations (either condition 1 or condition 3). ## Solutions -Prefix Sum +**Solution 1: Counting + Enumeration** + +First, we count the number of occurrences of each letter in strings $a$ and $b$, denoted as $cnt_1$ and $cnt_2$. + +Then, we consider condition $3$, i.e., every letter in $a$ and $b$ is the same. We just need to enumerate the final letter $c$, and then count the number of letters in $a$ and $b$ that are not $c$. This is the number of characters that need to be changed. + +Next, we consider conditions $1$ and $2$, i.e., every letter in $a$ is less than every letter in $b$, or every letter in $b$ is less than every letter in $a$. For condition $1$, we make all characters in string $a$ less than character $c$, and all characters in string $b$ not less than $c$. We enumerate $c$ to find the smallest answer. Condition $2$ is similar. + +The final answer is the minimum of the above three cases. + +The time complexity is $O(m + n + C^2)$, where $m$ and $n$ are the lengths of strings $a$ and $b$ respectively, and $C$ is the size of the character set. In this problem, $C = 26$. diff --git a/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README.md b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README.md index f910a8aa316c9..0ccfd0aa5b3c3 100644 --- a/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README.md +++ b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README.md @@ -54,7 +54,23 @@ -二维前缀异或,然后求第 k 大的值即可。 +**方法一:二维前缀异或 + 排序或快速选择** + +我们定义一个二维前缀异或数组 $s$,其中 $s[i][j]$ 表示矩阵前 $i$ 行和前 $j$ 列的元素异或运算的结果,即: + +$$ +s[i][j] = \bigoplus_{0 \leq x \leq i, 0 \leq y \leq j} matrix[x][y] +$$ + +而 $s[i][j]$ 可以由 $s[i - 1][j]$, $s[i][j - 1]$ 和 $s[i - 1][j - 1]$ 三个元素计算得到,即: + +$$ +s[i][j] = s[i - 1][j] \oplus s[i][j - 1] \oplus s[i - 1][j - 1] \oplus matrix[i - 1][j - 1] +$$ + +我们遍历矩阵,计算出所有的 $s[i][j]$,然后将其排序,最后返回第 $k$ 大的元素即可。如果不想使用排序,也可以使用快速选择算法,这样可以优化时间复杂度。 + +时间复杂度 $O(m \times n \times \log (m \times n))$ 或 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。 @@ -81,7 +97,6 @@ class Solution: ```java class Solution { - public int kthLargestValue(int[][] matrix, int k) { int m = matrix.length, n = matrix[0].length; int[][] s = new int[m + 1][n + 1]; @@ -140,6 +155,25 @@ func kthLargestValue(matrix [][]int, k int) int { } ``` +### **TypeScript** + +```ts +function kthLargestValue(matrix: number[][], k: number): number { + const m: number = matrix.length; + const n: number = matrix[0].length; + const s = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0)); + const ans: number[] = []; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + s[i + 1][j + 1] = s[i + 1][j] ^ s[i][j + 1] ^ s[i][j] ^ matrix[i][j]; + ans.push(s[i + 1][j + 1]); + } + } + ans.sort((a, b) => b - a); + return ans[k - 1]; +} +``` + ### **...** ``` diff --git a/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README_EN.md b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README_EN.md index 6401b3710907b..079d29c94d819 100644 --- a/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README_EN.md +++ b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/README_EN.md @@ -47,6 +47,24 @@ ## Solutions +**Solution 1: Two-dimensional Prefix XOR + Sorting or Quick Selection** + +We define a two-dimensional prefix XOR array $s$, where $s[i][j]$ represents the XOR result of the elements in the first $i$ rows and the first $j$ columns of the matrix, i.e., + +$$ +s[i][j] = \bigoplus_{0 \leq x \leq i, 0 \leq y \leq j} matrix[x][y] +$$ + +And $s[i][j]$ can be calculated from the three elements $s[i - 1][j]$, $s[i][j - 1]$ and $s[i - 1][j - 1]$, i.e., + +$$ +s[i][j] = s[i - 1][j] \oplus s[i][j - 1] \oplus s[i - 1][j - 1] \oplus matrix[i - 1][j - 1] +$$ + +We traverse the matrix, calculate all $s[i][j]$, then sort them, and finally return the $k$th largest element. If you don't want to use sorting, you can also use the quick selection algorithm, which can optimize the time complexity. + +The time complexity is $O(m \times n \times \log (m \times n))$ or $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, respectively. + ### **Python3** @@ -68,7 +86,6 @@ class Solution: ```java class Solution { - public int kthLargestValue(int[][] matrix, int k) { int m = matrix.length, n = matrix[0].length; int[][] s = new int[m + 1][n + 1]; @@ -127,6 +144,25 @@ func kthLargestValue(matrix [][]int, k int) int { } ``` +### **TypeScript** + +```ts +function kthLargestValue(matrix: number[][], k: number): number { + const m: number = matrix.length; + const n: number = matrix[0].length; + const s = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0)); + const ans: number[] = []; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + s[i + 1][j + 1] = s[i + 1][j] ^ s[i][j + 1] ^ s[i][j] ^ matrix[i][j]; + ans.push(s[i + 1][j + 1]); + } + } + ans.sort((a, b) => b - a); + return ans[k - 1]; +} +``` + ### **...** ``` diff --git a/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/Solution.ts b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/Solution.ts new file mode 100644 index 0000000000000..cb4b51977f0d0 --- /dev/null +++ b/solution/1700-1799/1738.Find Kth Largest XOR Coordinate Value/Solution.ts @@ -0,0 +1,14 @@ +function kthLargestValue(matrix: number[][], k: number): number { + const m: number = matrix.length; + const n: number = matrix[0].length; + const s = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0)); + const ans: number[] = []; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + s[i + 1][j + 1] = s[i + 1][j] ^ s[i][j + 1] ^ s[i][j] ^ matrix[i][j]; + ans.push(s[i + 1][j + 1]); + } + } + ans.sort((a, b) => b - a); + return ans[k - 1]; +} diff --git a/solution/1700-1799/1739.Building Boxes/README.md b/solution/1700-1799/1739.Building Boxes/README.md index c29f0a7060c7a..c8147d435fd47 100644 --- a/solution/1700-1799/1739.Building Boxes/README.md +++ b/solution/1700-1799/1739.Building Boxes/README.md @@ -69,7 +69,7 @@ 如果此时盒子还有剩余,那么可以从最低一层继续摆放,假设摆放 $i$ 个,那么累计可摆放的盒子个数为 $1+2+\cdots+i$。 -时间复杂度 $O(\sqrt{n})$,空间复杂度 $O(1)$。其中 $n$ 为题目给定的盒子数量。 +时间复杂度 $O(\sqrt{n})$,其中 $n$ 为题目给定的盒子数量。空间复杂度 $O(1)$。 diff --git a/solution/1700-1799/1739.Building Boxes/README_EN.md b/solution/1700-1799/1739.Building Boxes/README_EN.md index 9008d66e0fdc9..346766ad96fc3 100644 --- a/solution/1700-1799/1739.Building Boxes/README_EN.md +++ b/solution/1700-1799/1739.Building Boxes/README_EN.md @@ -55,6 +55,16 @@ These boxes are placed in the corner of the room, where the corner is on the bac ## Solutions +**Solution 1: Mathematical Rule** + +According to the problem description, the box with the highest number of layers needs to be placed in the corner of the wall, and the arrangement of the boxes is in a step-like shape, which can minimize the number of boxes touching the ground. + +Assume that the boxes are arranged in $k$ layers. From top to bottom, if each layer is filled, then the number of boxes in each layer is $1, 1+2, 1+2+3, \cdots, 1+2+\cdots+k$. + +If there are still remaining boxes at this point, they can continue to be placed from the lowest layer. Assume that $i$ boxes are placed, then the cumulative number of boxes that can be placed is $1+2+\cdots+i$. + +The time complexity is $O(\sqrt{n})$, where $n$ is the number of boxes given in the problem. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2500-2599/2563.Count the Number of Fair Pairs/README.md b/solution/2500-2599/2563.Count the Number of Fair Pairs/README.md index 36cd9486017e0..e16d4de115741 100644 --- a/solution/2500-2599/2563.Count the Number of Fair Pairs/README.md +++ b/solution/2500-2599/2563.Count the Number of Fair Pairs/README.md @@ -30,7 +30,7 @@
 输入:nums = [1,7,9,2,5], lower = 11, upper = 11
 输出:1
-解释:只有单个公平数对:(2,3) 。
+解释:只有单个公平数对:(2,9) 。
 

 

diff --git a/solution/2600-2699/2693.Call Function with Custom Context/README_EN.md b/solution/2600-2699/2693.Call Function with Custom Context/README_EN.md index 5b7890dec324a..97c0eebb69fce 100644 --- a/solution/2600-2699/2693.Call Function with Custom Context/README_EN.md +++ b/solution/2600-2699/2693.Call Function with Custom Context/README_EN.md @@ -51,7 +51,7 @@ args = [{"item": "burger"}, 10, 1.1]

 

Constraints:

-
    +
    • typeof args[0] == 'object' and args[0] != null
    • 1 <= args.length <= 100
    • 2 <= JSON.stringify(args[0]).length <= 105
    • diff --git a/solution/2700-2799/2700.Differences Between Two Objects/README_EN.md b/solution/2700-2799/2700.Differences Between Two Objects/README_EN.md index a31be0b0bd603..fd6cde0bd89af 100644 --- a/solution/2700-2799/2700.Differences Between Two Objects/README_EN.md +++ b/solution/2700-2799/2700.Differences Between Two Objects/README_EN.md @@ -6,7 +6,9 @@

      Write a function that accepts two deeply nested objects or arrays obj1 and obj2 and returns a new object representing their differences.

      -

      The function should compare the properties of the two objects and identify any changes. The returned object should only contains keys where the value is different from obj1 to obj2. For each changed key, the value should be represented as an array [obj1 value, obj2 value]. Keys that exist in one object but not in the other should not be included in the returned object. When comparing two arrays, the indices of the arrays are considered to be their keys. The end result should be a deeply nested object where each leaf value is a difference array.

      +

      The function should compare the properties of the two objects and identify any changes. The returned object should only contains keys where the value is different from obj1 to obj2.

      + +

      For each changed key, the value should be represented as an array [obj1 value, obj2 value]. Keys that exist in one object but not in the other should not be included in the returned object. When comparing two arrays, the indices of the arrays are considered to be their keys. The end result should be a deeply nested object where each leaf value is a difference array.

      You may assume that both objects are the output of JSON.parse.

      diff --git a/solution/2700-2799/2715.Timeout Cancellation/README_EN.md b/solution/2700-2799/2715.Timeout Cancellation/README_EN.md index 423d1c91a44d1..4a4cd7e96a77e 100644 --- a/solution/2700-2799/2715.Timeout Cancellation/README_EN.md +++ b/solution/2700-2799/2715.Timeout Cancellation/README_EN.md @@ -24,26 +24,8 @@ setTimeout(cancelFn, cancelTimeMs) Output: [{"time": 20, "returned": 10}] Explanation: const cancelTimeMs = 50; -const result = []; - -const fn = (x) => x * 5; - -const start = performance.now(); - -const log = (...argsArr) => { - const diff = Math.floor(performance.now() - start); - result.push({"time": diff, "returned": fn(...argsArr)}); -} -      -const cancel = cancellable(log, [2], 20); - -const maxT = Math.max(t, 50); -           -setTimeout(cancel, cancelTimeMs); - -setTimeout(() => { -     console.log(result); // [{"time":20,"returned":10}] -}, maxT + 15); +const cancelFn = cancellable((x) => x * 5, [2], 20); +setTimeout(cancelFn, cancelTimeMs); The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened after the execution of fn(2) at 20ms. @@ -55,6 +37,9 @@ The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), wh Output: [] Explanation: const cancelTimeMs = 50; +const cancelFn = cancellable((x) => x**2, [2], 100); +setTimeout(cancelFn, cancelTimeMs); + The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened before the execution of fn(2) at 100ms, resulting in fn(2) never being called. @@ -65,6 +50,9 @@ The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), wh Output: [{"time": 30, "returned": 8}] Explanation: const cancelTimeMs = 100; +const cancelFn = cancellable((x1, x2) => x1 * x2, [2,4], 30); +setTimeout(cancelFn, cancelTimeMs); + The cancellation was scheduled to occur after a delay of cancelTimeMs (100ms), which happened after the execution of fn(2,4) at 30ms. diff --git a/solution/2700-2799/2724.Sort By/README_EN.md b/solution/2700-2799/2724.Sort By/README_EN.md index 64b2f73b8b791..00feabdacc972 100644 --- a/solution/2700-2799/2724.Sort By/README_EN.md +++ b/solution/2700-2799/2724.Sort By/README_EN.md @@ -37,8 +37,8 @@

      Constraints:

        -
      • arr is a valid JSON array
      • -
      • fn is a function that returns a number
      • +
      • arr is a valid JSON array
      • +
      • fn is a function that returns a number
      • 1 <= arr.length <= 5 * 105
      diff --git a/solution/2700-2799/2725.Interval Cancellation/README_EN.md b/solution/2700-2799/2725.Interval Cancellation/README_EN.md index 80222d6de91fe..9c9b6af7f9989 100644 --- a/solution/2700-2799/2725.Interval Cancellation/README_EN.md +++ b/solution/2700-2799/2725.Interval Cancellation/README_EN.md @@ -23,23 +23,9 @@ {"time": 175, "returned": 8} ] Explanation: -const result = []; -const fn = (x) => x * 2; const cancelTimeMs = 190; - -const start = performance.now(); - -const log = (...argsArr) => { - const diff = Math.floor(performance.now() - start); - result.push({"time": diff, "returned": fn(...argsArr)}); -} - -const cancel = cancellable(log, [4], 35); -setTimeout(cancel, cancelTimeMs); - -setTimeout(() => { - console.log(result); // Output - }, cancelTimeMs + 50) +const cancelFn = cancellable((x) => x * 2, [4], 35); +setTimeout(cancelFn, cancelTimeMs); Every 35ms, fn(4) is called. Until t=190ms, then it is cancelled. 1st fn call is at 0ms. fn(4) returns 8. @@ -65,7 +51,9 @@ Cancelled at 190ms {"time": 150, "returned": 10} ] Explanation: -const cancelTimeMs = 165; +const cancelTimeMs = 165; +const cancelFn = cancellable((x1, x2) => (x1 * x2), [2, 5], 30) +setTimeout(cancelFn, cancelTimeMs) Every 30ms, fn(2, 5) is called. Until t=165ms, then it is cancelled. 1st fn call is at 0ms  @@ -90,6 +78,8 @@ Cancelled at 165ms ] Explanation: const cancelTimeMs = 180; +const cancelFn = cancellable((x1, x2, x3) => (x1 + x2 + x3), [5, 1, 3], 50) +setTimeout(cancelFn, cancelTimeMs) Every 50ms, fn(5, 1, 3) is called. Until t=180ms, then it is cancelled. 1st fn call is at 0ms diff --git a/solution/2700-2799/2754.Bind Function to Context/README_EN.md b/solution/2700-2799/2754.Bind Function to Context/README_EN.md index 61640ed6fadce..c20407dfad9ad 100644 --- a/solution/2700-2799/2754.Bind Function to Context/README_EN.md +++ b/solution/2700-2799/2754.Bind Function to Context/README_EN.md @@ -68,7 +68,7 @@ boundFunc(); // "My name is Kathy"

      Constraints:

        -
      • obj is a non-null object
      • +
      • obj is a non-null object
      • 0 <= inputs.length <= 100
      diff --git a/solution/2700-2799/2756.Query Batching/README_EN.md b/solution/2700-2799/2756.Query Batching/README_EN.md index c97a5c2e2adae..723d839c0a163 100644 --- a/solution/2700-2799/2756.Query Batching/README_EN.md +++ b/solution/2700-2799/2756.Query Batching/README_EN.md @@ -23,8 +23,6 @@

      Throttle info

      -

       

      -

       

      Example 1:

      @@ -119,7 +117,7 @@ queryMultiple(['f']) is called at t=350ms, it is resolved at 450ms
    • 0 <= t <= 1000
    • 0 <= calls.length <= 10
    • 1 <= key.length <= 100
    • -
    • all keys are unique
    • +
    • All keys are unique
    ## Solutions diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README.md" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README.md" similarity index 97% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README.md" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README.md" index 964ab6057909c..cacf01ce645b3 100644 --- "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README.md" +++ "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README.md" @@ -1,6 +1,6 @@ # [2764. 数组是否表示某二叉树的前序遍历](https://leetcode.cn/problems/is-array-a-preorder-of-some-binary-tree) -[English Version](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) +[English Version](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) ## 题目描述 @@ -25,7 +25,7 @@ 我们可以验证这是树的前序遍历,首先访问节点 0,然后对左子节点进行前序遍历,即 [1] ,然后对右子节点进行前序遍历,即 [2,3,4] 。 -

    +

    示例 2:

    @@ -36,7 +36,7 @@ 对于前序遍历,首先访问节点 0,然后对左子节点进行前序遍历,即 [1,3,4],但是我们可以看到在给定的顺序中,2 位于 1 和 3 之间,因此它不是树的前序遍历。 -

    +

     

    diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" similarity index 93% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" index 09610786d812e..f6bc683163e36 100644 --- "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" +++ "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/README_EN.md" @@ -1,14 +1,14 @@ -# [2764. is Array a Preorder of Some ‌Binary Tree](https://leetcode.com/problems/is-array-a-preorder-of-some-binary-tree) +# [2764. Is Array a Preorder of Some ‌Binary Tree](https://leetcode.com/problems/is-array-a-preorder-of-some-binary-tree) -[中文文档](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) +[中文文档](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) ## Description

    Given a 0-indexed integer 2D array nodes, your task is to determine if the given array represents the preorder traversal of some binary tree.

    -

    For each index i, nodes[i] = [id, parentId], where id is the id of the node at the index i and parentId is the id of its parent in the tree (if the node has no parent, then parentId = -1).

    +

    For each index i, nodes[i] = [id, parentId], where id is the id of the node at the index i and parentId is the id of its parent in the tree (if the node has no parent, then parentId == -1).

    -

    Return true if the given array represents the preorder traversal of some tree, and false otherwise.

    +

    Return true if the given array represents the preorder traversal of some tree, and false otherwise.

    Note: the preorder traversal of a tree is a recursive way to traverse a tree in which we first visit the current node, then we do the preorder traversal for the left child, and finally, we do it for the right child.

    @@ -22,7 +22,7 @@ We can show that this is the preorder traversal of the tree, first we visit node 0, then we do the preorder traversal of the right child which is [1], then we do the preorder traversal of the left child which is [2,3,4]. -

    +

    Example 2:

    @@ -33,7 +33,7 @@ We can show that this is the preorder traversal of the tree, first we visit node For the preorder traversal, first we visit node 0, then we do the preorder traversal of the right child which is [1,3,4], but we can see that in the given order, 2 comes between 1 and 3, so, it's not the preorder traversal of the tree. -

    +

     

    Constraints:

    diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.cpp" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.cpp" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.cpp" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.cpp" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.go" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.go" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.go" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.go" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.java" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.java" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.java" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.java" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.py" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.py" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.py" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.py" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.ts" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.ts" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/Solution.ts" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/Solution.ts" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/images/1.png" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/images/1.png" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/images/1.png" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/images/1.png" diff --git "a/solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/images/2.png" "b/solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/images/2.png" similarity index 100% rename from "solution/2700-2799/2764.is Array a Preorder of Some \342\200\214Binary Tree/images/2.png" rename to "solution/2700-2799/2764.Is Array a Preorder of Some \342\200\214Binary Tree/images/2.png" diff --git a/solution/2700-2799/2774.Array Upper Bound/README_EN.md b/solution/2700-2799/2774.Array Upper Bound/README_EN.md index 8e06c07a1108f..6d6d17e5247f8 100644 --- a/solution/2700-2799/2774.Array Upper Bound/README_EN.md +++ b/solution/2700-2799/2774.Array Upper Bound/README_EN.md @@ -39,6 +39,9 @@
  • nums is sorted in ascending order.
+

 

+Follow up: Can you write an algorithm with O(log n) runtime complexity? + ## Solutions diff --git a/solution/2700-2799/2776.Convert Callback Based Function to Promise Based Function/README_EN.md b/solution/2700-2799/2776.Convert Callback Based Function to Promise Based Function/README_EN.md index fe35ce8c098ee..269e80ba8a88c 100644 --- a/solution/2700-2799/2776.Convert Callback Based Function to Promise Based Function/README_EN.md +++ b/solution/2700-2799/2776.Convert Callback Based Function to Promise Based Function/README_EN.md @@ -6,7 +6,9 @@

Write a function that accepts another function fn and converts the callback-based function into a promise-based function. 

-

The promisify function takes in a function fn that accepts a callback as its first argument and also any additional arguments. It returns a new function that returns a promise instead. The returned promise should resolve with the result of the original function when the callback is called with a successful response, and reject with the error when the callback is called with an error. The returned promise-based function should accept the additional arguments as inputs.

+

The function fn takes a callback as its first argument, along with any additional arguments args passed as separate inputs.

+ +

The promisify function returns a new function that should return a promise. The promise should resolve with the argument passed as the first parameter of the callback when the callback is invoked without error, and reject with the error when the callback is called with an error as the second argument.

The following is an example of a function that could be passed into promisify.

diff --git a/solution/2700-2799/2796.Repeat String/README_EN.md b/solution/2700-2799/2796.Repeat String/README_EN.md index 5557e88d77a17..6262e1a4d35e7 100644 --- a/solution/2700-2799/2796.Repeat String/README_EN.md +++ b/solution/2700-2799/2796.Repeat String/README_EN.md @@ -37,8 +37,7 @@

Constraints:

    -
  • 1 <= str.length <= 1000
  • -
  • 1 <= times <= 1000
  • +
  • 1 <= str.length, times <= 105
## Solutions diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index c07f1614bd397..6ee852dec4315 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -250,4 +250,15 @@ ## 版权 -著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 [@yanglbme](mailto:contact@yanglibin.info) 获得授权,非商业转载请注明出处。 +本项目著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 @yanglbme 获得授权,非商业转载请注明出处。 + +## 联系我们 + +欢迎各位小伙伴们添加 @yanglbme 的个人微信(微信号:YLB0109),备注 「**leetcode**」。后续我们会创建算法、技术相关的交流群,大家一起交流学习,分享经验,共同进步。 + +| | +| ------------------------------------------------------------------------------------------------------------------------------ | + +## 许可证 + +知识共享 版权归属-相同方式共享 4.0 国际 公共许可证 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index aad41ef999334..07fb8ec7a3df1 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -248,4 +248,15 @@ Press Control + F(or Command + F on ## Copyright -[@Doocs](https://github.com/doocs) +The copyright of this project belongs to [Doocs](https://github.com/doocs) community. For commercial reprints, please contact [@yanglbme](mailto:contact@yanglibin.info) for authorization. For non-commercial reprints, please indicate the source. + +## Contact Us + +We welcome everyone to add @yanglbme's personal WeChat (WeChat ID: YLB0109), with the note "leetcode". In the future, we will create algorithm and technology related discussion groups, where we can learn and share experiences together, and make progress together. + +| | +| --------------------------------------------------------------------------------------------------------------------------------- | + +## License + +This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/solution/JAVASCRIPT_README.md b/solution/JAVASCRIPT_README.md index e24d9b431fc61..c95287c9c0c86 100644 --- a/solution/JAVASCRIPT_README.md +++ b/solution/JAVASCRIPT_README.md @@ -80,4 +80,15 @@ ## 版权 -著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 [@yanglbme](mailto:contact@yanglibin.info) 获得授权,非商业转载请注明出处。 +本项目著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 @yanglbme 获得授权,非商业转载请注明出处。 + +## 联系我们 + +欢迎各位小伙伴们添加 @yanglbme 的个人微信(微信号:YLB0109),备注 「**leetcode**」。后续我们会创建算法、技术相关的交流群,大家一起交流学习,分享经验,共同进步。 + +| | +| ------------------------------------------------------------------------------------------------------------------------------ | + +## 许可证 + +知识共享 版权归属-相同方式共享 4.0 国际 公共许可证 diff --git a/solution/JAVASCRIPT_README_EN.md b/solution/JAVASCRIPT_README_EN.md index 6d0c0dbc0b136..e6781d310ba50 100644 --- a/solution/JAVASCRIPT_README_EN.md +++ b/solution/JAVASCRIPT_README_EN.md @@ -78,4 +78,15 @@ Press Control + F(or Command + F on ## Copyright -[@Doocs](https://github.com/doocs) +The copyright of this project belongs to [Doocs](https://github.com/doocs) community. For commercial reprints, please contact [@yanglbme](mailto:contact@yanglibin.info) for authorization. For non-commercial reprints, please indicate the source. + +## Contact Us + +We welcome everyone to add @yanglbme's personal WeChat (WeChat ID: YLB0109), with the note "leetcode". In the future, we will create algorithm and technology related discussion groups, where we can learn and share experiences together, and make progress together. + +| | +| --------------------------------------------------------------------------------------------------------------------------------- | + +## License + +This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/solution/README.md b/solution/README.md index b2fd88bdf9cdb..aea51e28c1ce8 100644 --- a/solution/README.md +++ b/solution/README.md @@ -2774,7 +2774,7 @@ | 2761 | [和等于目标值的质数对](/solution/2700-2799/2761.Prime%20Pairs%20With%20Target%20Sum/README.md) | `数组`,`数学`,`枚举`,`数论` | 中等 | 第 352 场周赛 | | 2762 | [不间断子数组](/solution/2700-2799/2762.Continuous%20Subarrays/README.md) | `队列`,`数组`,`有序集合`,`滑动窗口`,`单调队列`,`堆(优先队列)` | 中等 | 第 352 场周赛 | | 2763 | [所有子数组中不平衡数字之和](/solution/2700-2799/2763.Sum%20of%20Imbalance%20Numbers%20of%20All%20Subarrays/README.md) | `数组`,`哈希表`,`有序集合` | 困难 | 第 352 场周赛 | -| 2764 | [数组是否表示某二叉树的前序遍历](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) | `栈`,`树`,`深度优先搜索`,`二叉树` | 中等 | 🔒 | +| 2764 | [数组是否表示某二叉树的前序遍历](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) | `栈`,`树`,`深度优先搜索`,`二叉树` | 中等 | 🔒 | | 2765 | [最长交替子序列](/solution/2700-2799/2765.Longest%20Alternating%20Subarray/README.md) | `数组`,`枚举` | 简单 | 第 108 场双周赛 | | 2766 | [重新放置石块](/solution/2700-2799/2766.Relocate%20Marbles/README.md) | `数组`,`哈希表`,`排序`,`模拟` | 中等 | 第 108 场双周赛 | | 2767 | [将字符串分割为最少的美丽子字符串](/solution/2700-2799/2767.Partition%20String%20Into%20Minimum%20Beautiful%20Substrings/README.md) | `哈希表`,`字符串`,`动态规划`,`回溯` | 中等 | 第 108 场双周赛 | @@ -2989,8 +2989,4 @@ 欢迎各位小伙伴们添加 @yanglbme 的个人微信(微信号:YLB0109),备注 「**leetcode**」。后续我们会创建算法、技术相关的交流群,大家一起交流学习,分享经验,共同进步。 | | -| ------------------------------------------------------------------------------------------------------------------------------ | - -## 许可证 - -知识共享 版权归属-相同方式共享 4.0 国际 公共许可证 \ No newline at end of file +| ------------------------------------------------------------------------------------------------------------------------------ | \ No newline at end of file diff --git a/solution/README_EN.md b/solution/README_EN.md index 840750846244b..fbaba2fd8a2cf 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -2772,7 +2772,7 @@ Press Control + F(or Command + F on | 2761 | [Prime Pairs With Target Sum](/solution/2700-2799/2761.Prime%20Pairs%20With%20Target%20Sum/README_EN.md) | `Array`,`Math`,`Enumeration`,`Number Theory` | Medium | Weekly Contest 352 | | 2762 | [Continuous Subarrays](/solution/2700-2799/2762.Continuous%20Subarrays/README_EN.md) | `Queue`,`Array`,`Ordered Set`,`Sliding Window`,`Monotonic Queue`,`Heap (Priority Queue)` | Medium | Weekly Contest 352 | | 2763 | [Sum of Imbalance Numbers of All Subarrays](/solution/2700-2799/2763.Sum%20of%20Imbalance%20Numbers%20of%20All%20Subarrays/README_EN.md) | `Array`,`Hash Table`,`Ordered Set` | Hard | Weekly Contest 352 | -| 2764 | [is Array a Preorder of Some ‌Binary Tree](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) | `Stack`,`Tree`,`Depth-First Search`,`Binary Tree` | Medium | 🔒 | +| 2764 | [Is Array a Preorder of Some ‌Binary Tree](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) | `Stack`,`Tree`,`Depth-First Search`,`Binary Tree` | Medium | 🔒 | | 2765 | [Longest Alternating Subarray](/solution/2700-2799/2765.Longest%20Alternating%20Subarray/README_EN.md) | `Array`,`Enumeration` | Easy | Biweekly Contest 108 | | 2766 | [Relocate Marbles](/solution/2700-2799/2766.Relocate%20Marbles/README_EN.md) | `Array`,`Hash Table`,`Sorting`,`Simulation` | Medium | Biweekly Contest 108 | | 2767 | [Partition String Into Minimum Beautiful Substrings](/solution/2700-2799/2767.Partition%20String%20Into%20Minimum%20Beautiful%20Substrings/README_EN.md) | `Hash Table`,`String`,`Dynamic Programming`,`Backtracking` | Medium | Biweekly Contest 108 | @@ -2991,4 +2991,4 @@ We welcome everyone to add @yanglbme's personal WeChat (WeChat ID: YLB0109), wit ## License -This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. +This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. \ No newline at end of file diff --git a/solution/summary.md b/solution/summary.md index c0c71264c584e..78016bbc0885b 100644 --- a/solution/summary.md +++ b/solution/summary.md @@ -2817,7 +2817,7 @@ - [2761.和等于目标值的质数对](/solution/2700-2799/2761.Prime%20Pairs%20With%20Target%20Sum/README.md) - [2762.不间断子数组](/solution/2700-2799/2762.Continuous%20Subarrays/README.md) - [2763.所有子数组中不平衡数字之和](/solution/2700-2799/2763.Sum%20of%20Imbalance%20Numbers%20of%20All%20Subarrays/README.md) - - [2764.数组是否表示某二叉树的前序遍历](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) + - [2764.数组是否表示某二叉树的前序遍历](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README.md) - [2765.最长交替子序列](/solution/2700-2799/2765.Longest%20Alternating%20Subarray/README.md) - [2766.重新放置石块](/solution/2700-2799/2766.Relocate%20Marbles/README.md) - [2767.将字符串分割为最少的美丽子字符串](/solution/2700-2799/2767.Partition%20String%20Into%20Minimum%20Beautiful%20Substrings/README.md) diff --git a/solution/summary_en.md b/solution/summary_en.md index 8ca362264e6c1..4a4cb39a6461a 100644 --- a/solution/summary_en.md +++ b/solution/summary_en.md @@ -2817,7 +2817,7 @@ - [2761.Prime Pairs With Target Sum](/solution/2700-2799/2761.Prime%20Pairs%20With%20Target%20Sum/README_EN.md) - [2762.Continuous Subarrays](/solution/2700-2799/2762.Continuous%20Subarrays/README_EN.md) - [2763.Sum of Imbalance Numbers of All Subarrays](/solution/2700-2799/2763.Sum%20of%20Imbalance%20Numbers%20of%20All%20Subarrays/README_EN.md) - - [2764.is Array a Preorder of Some ‌Binary Tree](/solution/2700-2799/2764.is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) + - [2764.Is Array a Preorder of Some ‌Binary Tree](/solution/2700-2799/2764.Is%20Array%20a%20Preorder%20of%20Some%20%E2%80%8CBinary%20Tree/README_EN.md) - [2765.Longest Alternating Subarray](/solution/2700-2799/2765.Longest%20Alternating%20Subarray/README_EN.md) - [2766.Relocate Marbles](/solution/2700-2799/2766.Relocate%20Marbles/README_EN.md) - [2767.Partition String Into Minimum Beautiful Substrings](/solution/2700-2799/2767.Partition%20String%20Into%20Minimum%20Beautiful%20Substrings/README_EN.md) diff --git a/solution/template.md b/solution/template.md index b139c1832a136..4a83ccc7df5a8 100644 --- a/solution/template.md +++ b/solution/template.md @@ -23,6 +23,10 @@ | | | ------------------------------------------------------------------------------------------------------------------------------ | +## 许可证 + +知识共享 版权归属-相同方式共享 4.0 国际 公共许可证 + ---