Skip to content

Commit ecfdfa6

Browse files
authored
feat: add solutions for weekly contest 484 (#4962)
1 parent 0effcc5 commit ecfdfa6

File tree

14 files changed

+460
-15
lines changed

14 files changed

+460
-15
lines changed

solution/3800-3899/3803.Count Residue Prefixes/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3803.Co
9292

9393
<!-- solution:start -->
9494

95-
### 方法一
95+
### 方法一:哈希表
96+
97+
我们用一个哈希表 $\textit{st}$ 来记录当前前缀中出现过的不同字符的集合。遍历字符串 $s$ 的每个字符 $c$,将其加入集合 $\textit{st}$ 中,然后判断当前前缀的长度对 $3$ 取模的结果是否等于集合 $\textit{st}$ 的大小。如果相等,则说明当前前缀是一个残差前缀,答案加 $1$。
98+
99+
遍历结束后,返回答案即可。
100+
101+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。
96102

97103
<!-- tabs:start -->
98104

solution/3800-3899/3803.Count Residue Prefixes/README_EN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,13 @@ A <strong>prefix</strong> of a string is a <strong>non-empty substring</strong>
8181

8282
<!-- solution:start -->
8383

84-
### Solution 1
84+
### Solution 1: Hash Table
85+
86+
We use a hash table $\textit{st}$ to record the set of distinct characters that have appeared in the current prefix. We iterate through each character $c$ in the string $s$, add it to the set $\textit{st}$, and then check if the length of the current prefix modulo $3$ equals the size of the set $\textit{st}$. If they are equal, it means the current prefix is a residue prefix, and we increment the answer by $1$.
87+
88+
After the iteration, we return the answer.
89+
90+
The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the length of the string $s$.
8591

8692
<!-- tabs:start -->
8793

solution/3800-3899/3804.Number of Centered Subarrays/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3804.Nu
6969

7070
<!-- solution:start -->
7171

72-
### 方法一
72+
### 方法一:哈希表 + 枚举
73+
74+
我们枚举所有子数组的起始下标 $i$,然后从下标 $i$ 开始枚举子数组的结束下标 $j$,计算子数组 $nums[i \ldots j]$ 的元素之和 $s$,并将子数组中的所有元素加入哈希表 $\textit{st}$ 中。每次枚举结束后,判断 $s$ 是否在哈希表 $\textit{st}$ 中出现过,如果出现过,则说明子数组 $nums[i \ldots j]$ 是一个中心子数组,答案加 $1$。
75+
76+
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
7377

7478
<!-- tabs:start -->
7579

solution/3800-3899/3804.Number of Centered Subarrays/README_EN.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3804.Nu
6767

6868
<!-- solution:start -->
6969

70-
### Solution 1
70+
### Solution 1: Hash Table + Enumeration
71+
72+
We enumerate all starting indices $i$ of subarrays, then starting from index $i$, we enumerate the ending index $j$ of the subarray, calculate the sum $s$ of elements in the subarray $nums[i \ldots j]$, and add all elements in the subarray to the hash table $\textit{st}$. After each enumeration, we check if $s$ appears in the hash table $\textit{st}$. If it does, it means the subarray $nums[i \ldots j]$ is a centered subarray, and we increment the answer by $1$.
73+
74+
The time complexity is $O(n^2)$ and the space complexity is $O(n)$, where $n$ is the length of the array $nums$.
7175

7276
<!-- tabs:start -->
7377

solution/3800-3899/3805.Count Caesar Cipher Pairs/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3805.Co
8686

8787
<!-- solution:start -->
8888

89-
### 方法一
89+
### 方法一:字符串转换 + 计数
90+
91+
我们可以将每个字符串转换为一个统一的形式,具体做法是将字符串的第一个字符转换为 `'z'`,然后将字符串中的其他字符按照相同的偏移量进行转换。这样,所有相似的字符串都会被转换为相同的形式。我们使用一个哈希表 $\textit{cnt}$ 来记录每个转换后的字符串出现的次数。
92+
93+
最后,我们遍历哈希表,计算每个字符串出现次数 $v$ 的组合数 $\frac{v(v-1)}{2}$,将其累加到答案中。
94+
95+
时间复杂度 $O(n \times m)$,空间复杂度 $O(n \times m)$。其中 $n$ 是字符串数组的长度,而 $m$ 是字符串的长度。
9096

9197
<!-- tabs:start -->
9298

solution/3800-3899/3805.Count Caesar Cipher Pairs/README_EN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3805.Co
8484

8585
<!-- solution:start -->
8686

87-
### Solution 1
87+
### Solution 1: String Transformation + Counting
88+
89+
We can transform each string into a unified form. Specifically, we convert the first character of the string to `'z'`, and then transform the other characters in the string with the same offset. This way, all similar strings will be transformed into the same form. We use a hash table $\textit{cnt}$ to record the number of occurrences of each transformed string.
90+
91+
Finally, we iterate through the hash table, calculate the combination number $\frac{v(v-1)}{2}$ for each string's occurrence count $v$, and add it to the answer.
92+
93+
The time complexity is $O(n \times m)$ and the space complexity is $O(n \times m)$, where $n$ is the length of the string array and $m$ is the length of the strings.
8894

8995
<!-- tabs:start -->
9096

solution/3800-3899/3805.Count Caesar Cipher Pairs/Solution.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public long countPairs(String[] words) {
66
char[] t = s.toCharArray();
77
int k = 'z' - t[0];
88
for (int i = 1; i < t.length; i++) {
9-
t[i] = (char)('a' + (t[i] - 'a' + k) % 26);
9+
t[i] = (char) ('a' + (t[i] - 'a' + k) % 26);
1010
}
1111
t[0] = 'z';
1212
cnt.merge(new String(t), 1, Integer::sum);

solution/3800-3899/3806.Maximum Bitwise AND After Increment Operations/README.md

Lines changed: 144 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,32 +92,172 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3806.Ma
9292

9393
<!-- solution:start -->
9494

95-
### 方法一
95+
### 方法一:试填法 + 位运算
96+
97+
我们从最高位开始枚举每一位,尝试将该位加入最终的按位与结果中。对于当前尝试的按位与结果 $\textit{target}$,我们计算将数组中的每个元素增加到至少 $\textit{target}$ 所需的最小操作数。
98+
99+
具体做法是找出 $\textit{target}$ 从高到低第一个位为 $1$,而当前元素对应位为 $0$ 的位置 $j - 1$,那么我们只需要将当前元素增加到 $\textit{target}$ 在低 $j$ 位的值即可,所需的操作数为 $(\textit{target} \& 2^{j} - 1) - (\textit{nums}[i] \& 2^{j} - 1)$。我们将所有元素所需的操作数存入数组 $\textit{cost}$ 中,并对其进行排序,取前 $m$ 个元素的操作数之和,如果不超过 $k$,则说明可以将按位与结果的该位加入最终结果中。
100+
101+
时间复杂度 $O(n \times \log n \times \log M)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度,而 $M$ 是数组 $\textit{nums}$ 中的最大值。
96102

97103
<!-- tabs:start -->
98104

99105
#### Python3
100106

101107
```python
102-
108+
class Solution:
109+
def maximumAND(self, nums: List[int], k: int, m: int) -> int:
110+
mx = (max(nums) + k).bit_length()
111+
ans = 0
112+
cost = [0] * len(nums)
113+
for bit in range(mx - 1, -1, -1):
114+
target = ans | (1 << bit)
115+
for i, x in enumerate(nums):
116+
j = (target & ~x).bit_length()
117+
mask = (1 << j) - 1
118+
cost[i] = (target & mask) - (x & mask)
119+
cost.sort()
120+
if sum(cost[:m]) <= k:
121+
ans = target
122+
return ans
103123
```
104124

105125
#### Java
106126

107127
```java
108-
128+
class Solution {
129+
public int maximumAND(int[] nums, int k, int m) {
130+
int max = 0;
131+
for (int x : nums) {
132+
max = Math.max(max, x);
133+
}
134+
max += k;
135+
136+
int mx = 32 - Integer.numberOfLeadingZeros(max);
137+
int n = nums.length;
138+
139+
int ans = 0;
140+
int[] cost = new int[n];
141+
142+
for (int bit = mx - 1; bit >= 0; bit--) {
143+
int target = ans | (1 << bit);
144+
for (int i = 0; i < n; i++) {
145+
int x = nums[i];
146+
int diff = target & ~x;
147+
int j = diff == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(diff);
148+
int mask = (1 << j) - 1;
149+
cost[i] = (target & mask) - (x & mask);
150+
}
151+
Arrays.sort(cost);
152+
long sum = 0;
153+
for (int i = 0; i < m; i++) {
154+
sum += cost[i];
155+
}
156+
if (sum <= k) {
157+
ans = target;
158+
}
159+
}
160+
161+
return ans;
162+
}
163+
}
109164
```
110165

111166
#### C++
112167

113168
```cpp
114-
169+
class Solution {
170+
public:
171+
int maximumAND(const vector<int>& nums, int k, int m) {
172+
int max_val = ranges::max(nums) + k;
173+
int mx = max_val > 0 ? 32 - __builtin_clz(max_val) : 0;
174+
175+
int ans = 0;
176+
vector<int> cost(nums.size());
177+
178+
for (int bit = mx - 1; bit >= 0; bit--) {
179+
int target = ans | (1 << bit);
180+
for (size_t i = 0; i < nums.size(); i++) {
181+
int x = nums[i];
182+
int diff = target & ~x;
183+
int j = diff == 0 ? 0 : 32 - __builtin_clz(diff);
184+
long long mask = (1L << j) - 1;
185+
cost[i] = (target & mask) - (x & mask);
186+
}
187+
188+
ranges::sort(cost);
189+
long long sum = accumulate(cost.begin(), cost.begin() + m, 0LL);
190+
if (sum <= k) {
191+
ans = target;
192+
}
193+
}
194+
195+
return ans;
196+
}
197+
};
115198
```
116199
117200
#### Go
118201
119202
```go
203+
func maximumAND(nums []int, k int, m int) int {
204+
mx := bits.Len(uint(slices.Max(nums) + k))
205+
206+
ans := 0
207+
cost := make([]int, len(nums))
208+
209+
for bit := mx - 1; bit >= 0; bit-- {
210+
target := ans | (1 << bit)
211+
for i, x := range nums {
212+
j := bits.Len(uint(target & ^x))
213+
mask := (1 << j) - 1
214+
cost[i] = (target & mask) - (x & mask)
215+
}
216+
sort.Ints(cost)
217+
sum := 0
218+
for i := 0; i < m; i++ {
219+
sum += cost[i]
220+
}
221+
if sum <= k {
222+
ans = target
223+
}
224+
}
225+
226+
return ans
227+
}
228+
```
120229

230+
#### TypeScript
231+
232+
```ts
233+
function maximumAND(nums: number[], k: number, m: number): number {
234+
const mx = 32 - Math.clz32(Math.max(...nums) + k);
235+
236+
let ans = 0;
237+
const n = nums.length;
238+
const cost = new Array(n);
239+
240+
for (let bit = mx - 1; bit >= 0; bit--) {
241+
let target = ans | (1 << bit);
242+
for (let i = 0; i < n; i++) {
243+
const x = nums[i];
244+
const diff = target & ~x;
245+
const j = diff === 0 ? 0 : 32 - Math.clz32(diff);
246+
const mask = (1 << j) - 1;
247+
cost[i] = (target & mask) - (x & mask);
248+
}
249+
cost.sort((a, b) => a - b);
250+
let sum = 0;
251+
for (let i = 0; i < m; i++) {
252+
sum += cost[i];
253+
}
254+
if (sum <= k) {
255+
ans = target;
256+
}
257+
}
258+
259+
return ans;
260+
}
121261
```
122262

123263
<!-- tabs:end -->

0 commit comments

Comments
 (0)