Skip to content

Commit 3683ce0

Browse files
committed
feat: add biweekly contest 183
1 parent 4f7bd51 commit 3683ce0

41 files changed

Lines changed: 1529 additions & 56 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,17 @@ impl Solution {
210210

211211
考虑相邻两个区间:
212212

213-
* 左侧区间 `left_chunk`
214-
* 右侧区间 `right_chunk`
213+
- 左侧区间 `left_chunk`
214+
- 右侧区间 `right_chunk`
215215

216216
若满足:
217217

218218
`max(left_chunk)` <= `min(right_chunk)`
219219

220220
则说明:
221-
* 左侧区间中的任意元素都不会大于右侧区间中的任意元素
222-
* 因此两个区间分别排序后,可以直接拼接成一个有序数组
221+
222+
- 左侧区间中的任意元素都不会大于右侧区间中的任意元素
223+
- 因此两个区间分别排序后,可以直接拼接成一个有序数组
223224

224225
于是,对于每个满足:
225226

@@ -241,15 +242,15 @@ $$
241242

242243
为了快速计算上述条件,我们预处理:
243244

244-
* `prefix_maxs[j]`表示:
245+
- `prefix_maxs[j]`表示:
245246

246247
$$
247248
\max(arr[:j + 1])
248249
$$
249250

250251
即前缀最大值。
251252

252-
* `suffix_min[j]`表示:
253+
- `suffix_min[j]`表示:
253254

254255
$$
255256
\min(arr[j:])
@@ -267,8 +268,8 @@ $$
267268

268269
成立,则说明:
269270

270-
* 左侧所有元素均不大于右侧所有元素
271-
* 因此可以在索引 $i$ 处分割数组
271+
- 左侧所有元素均不大于右侧所有元素
272+
- 因此可以在索引 $i$ 处分割数组
272273

273274
最终统计所有合法分割点数量即可。
274275

solution/0700-0799/0768.Max Chunks To Make Sorted II/README_EN.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,17 @@ after sorting each chunk individually, the entire array remains sorted.
210210

211211
Consider two adjacent chunks:
212212

213-
* left chunk: `left_chunk`
214-
* right chunk: `right_chunk`
213+
- left chunk: `left_chunk`
214+
- right chunk: `right_chunk`
215215

216216
If the following condition holds:
217217

218218
`max(left_chunk)` <= `min(right_chunk)`
219219

220220
it means:
221-
* every element in the left chunk is less than or equal to every element in the right chunk
222-
* therefore, after sorting both chunks independently, they can still be concatenated into a globally sorted array
221+
222+
- every element in the left chunk is less than or equal to every element in the right chunk
223+
- therefore, after sorting both chunks independently, they can still be concatenated into a globally sorted array
223224

224225
Thus, for every index $i$ satisfying:
225226

@@ -241,7 +242,7 @@ If true, then index $i$ can serve as a valid partition point.
241242

242243
To efficiently evaluate the above condition, we preprocess:
243244

244-
* `prefix_maxs[j]`
245+
- `prefix_maxs[j]`
245246

246247
which represents:
247248

@@ -251,7 +252,7 @@ $$
251252

252253
i.e. the prefix maximum.
253254

254-
* `suffix_min[j]`
255+
- `suffix_min[j]`
255256

256257
which represents:
257258

@@ -273,8 +274,8 @@ holds.
273274

274275
If true, then:
275276

276-
* every element on the left side is less than or equal to every element on the right side
277-
* therefore, the array can be partitioned at index $i$
277+
- every element on the left side is less than or equal to every element on the right side
278+
- therefore, the array can be partitioned at index $i$
278279

279280
Finally, count all valid partition points.
280281

solution/1300-1399/1340.Jump Game V/README.md

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ tags:
9090

9191
### 方法一:记忆化搜索
9292

93-
我们设计一个函数 $dfs(i)$,表示从下标 $i$ 开始跳跃能够访问的最大下标数。我们可以枚举 $i$ 的所有合法的跳跃目标 $j$,即 $i - d \leq j \leq i + d$,并且 $arr[i] \gt arr[j]$。对于每个合法的 $j$,我们可以递归地计算 $dfs(j)$,并取其中的最大值。最终的答案即为所有 $i$ 的 $dfs(i)$ 的最大值。
93+
我们设计一个函数 $\text{dfs}(i)$,表示从下标 $i$ 开始跳跃能够访问的最大下标数。我们可以枚举 $i$ 的所有合法的跳跃目标 $j$,即 $i - d \leq j \leq i + d$,并且 $\text{arr}[i] > \text{arr}[j]$。对于每个合法的 $j$,我们可以递归地计算 $\text{dfs}(j)$,并取其中的最大值。最终的答案即为所有 $i$ 的 $\text{dfs}(i)$ 的最大值。
9494

95-
我们可以使用记忆化搜索来优化这个过程,即使用一个数组 $f$ 记录每个下标的 $dfs$ 值,避免重复计算。
95+
我们可以使用记忆化搜索来优化这个过程,即使用一个数组 $f$ 记录每个下标的 $\text{dfs}$ 值,避免重复计算。
9696

97-
时间复杂度 $O(n \times d)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $arr$ 的长度。
97+
时间复杂度 $O(n \times d)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\text{arr}$ 的长度。
9898

9999
<!-- tabs:start -->
100100

@@ -172,7 +172,7 @@ public:
172172
int n = arr.size();
173173
int f[n];
174174
memset(f, 0, sizeof(f));
175-
function<int(int)> dfs = [&](int i) -> int {
175+
auto dfs = [&](this auto&& dfs, int i) -> int {
176176
if (f[i]) {
177177
return f[i];
178178
}
@@ -234,6 +234,81 @@ func maxJumps(arr []int, d int) (ans int) {
234234
}
235235
```
236236

237+
#### TypeScript
238+
239+
```typescript
240+
function maxJumps(arr: number[], d: number): number {
241+
const n = arr.length;
242+
const f: number[] = new Array(n).fill(0);
243+
const dfs = (i: number): number => {
244+
if (f[i] !== 0) {
245+
return f[i];
246+
}
247+
let ans = 1;
248+
for (let j = i - 1; j >= 0; j--) {
249+
if (i - j > d || arr[j] >= arr[i]) {
250+
break;
251+
}
252+
ans = Math.max(ans, 1 + dfs(j));
253+
}
254+
for (let j = i + 1; j < n; j++) {
255+
if (j - i > d || arr[j] >= arr[i]) {
256+
break;
257+
}
258+
ans = Math.max(ans, 1 + dfs(j));
259+
}
260+
f[i] = ans;
261+
return ans;
262+
};
263+
let ans = 0;
264+
for (let i = 0; i < n; i++) {
265+
ans = Math.max(ans, dfs(i));
266+
}
267+
return ans;
268+
}
269+
```
270+
271+
#### Rust
272+
273+
```rust
274+
impl Solution {
275+
pub fn max_jumps(arr: Vec<i32>, d: i32) -> i32 {
276+
fn dfs(i: usize, n: usize, d: usize, arr: &[i32], f: &mut Vec<i32>) -> i32 {
277+
if f[i] != 0 {
278+
return f[i];
279+
}
280+
let mut ans = 1;
281+
let mut j = (i as isize) - 1;
282+
while j >= 0 {
283+
if i - (j as usize) > d || arr[j as usize] >= arr[i] {
284+
break;
285+
}
286+
ans = ans.max(1 + dfs(j as usize, n, d, arr, f));
287+
j -= 1;
288+
}
289+
j = (i as isize) + 1;
290+
while (j as usize) < n {
291+
if j as usize - i > d || arr[j as usize] >= arr[i] {
292+
break;
293+
}
294+
ans = ans.max(1 + dfs(j as usize, n, d, arr, f));
295+
j += 1;
296+
}
297+
f[i] = ans;
298+
ans
299+
}
300+
let n = arr.len();
301+
let d = d as usize;
302+
let mut f = vec![0; n];
303+
let mut ans = 0;
304+
for i in 0..n {
305+
ans = ans.max(dfs(i, n, d, &arr, &mut f));
306+
}
307+
ans
308+
}
309+
}
310+
```
311+
237312
<!-- tabs:end -->
238313

239314
<!-- solution:end -->
@@ -242,6 +317,8 @@ func maxJumps(arr []int, d int) (ans int) {
242317

243318
### 方法二:排序 + 动态规划
244319

320+
我们可以将数组 $\text{arr}$ 中的每个元素 $x$ 与其下标 $i$ 组成一个元组 $(x, i)$,并将这些元组按照 $x$ 从小到大排序。
321+
245322
我们可以将数组 $arr$ 中的每个元素 $x$ 与其下标 $i$ 组成一个元组 $(x, i)$,并将这些元组按照 $x$ 从小到大排序。
246323

247324
接下来定义 $f[i]$ 表示从下标 $i$ 开始跳跃能够访问的最大下标数。初始时 $f[i] = 1$,即每个下标都可以单独作为一次跳跃。
@@ -330,7 +407,7 @@ public:
330407
f[i] = max(f[i], 1 + f[j]);
331408
}
332409
}
333-
return *max_element(f.begin(), f.end());
410+
return ranges::max(f);
334411
}
335412
};
336413
```
@@ -365,6 +442,74 @@ func maxJumps(arr []int, d int) int {
365442
}
366443
```
367444

445+
#### TypeScript
446+
447+
```ts
448+
function maxJumps(arr: number[], d: number): number {
449+
const n = arr.length;
450+
const f: number[] = new Array(n).fill(1);
451+
const idx: number[] = Array.from({ length: n }, (_, i) => i);
452+
idx.sort((a, b) => arr[a] - arr[b]);
453+
for (const i of idx) {
454+
for (let j = i - 1; j >= 0; j--) {
455+
if (i - j > d || arr[j] >= arr[i]) {
456+
break;
457+
}
458+
f[i] = Math.max(f[i], 1 + f[j]);
459+
}
460+
for (let j = i + 1; j < n; j++) {
461+
if (j - i > d || arr[j] >= arr[i]) {
462+
break;
463+
}
464+
f[i] = Math.max(f[i], 1 + f[j]);
465+
}
466+
}
467+
return Math.max(...f);
468+
}
469+
```
470+
471+
#### Rust
472+
473+
```rust
474+
impl Solution {
475+
pub fn max_jumps(arr: Vec<i32>, d: i32) -> i32 {
476+
let n = arr.len();
477+
let d = d as usize;
478+
479+
let mut idx: Vec<usize> = (0..n).collect();
480+
idx.sort_by_key(|&i| arr[i]);
481+
482+
let mut f = vec![1; n];
483+
484+
for &i in &idx {
485+
let mut j = i as i32 - 1;
486+
while j >= 0 {
487+
let k = j as usize;
488+
489+
if i - k > d || arr[k] >= arr[i] {
490+
break;
491+
}
492+
493+
f[i] = f[i].max(1 + f[k]);
494+
j -= 1;
495+
}
496+
497+
let mut j = i + 1;
498+
while j < n {
499+
if j - i > d || arr[j] >= arr[i] {
500+
break;
501+
}
502+
503+
f[i] = f[i].max(1 + f[j]);
504+
j += 1;
505+
}
506+
}
507+
508+
*f.iter().max().unwrap()
509+
}
510+
}
511+
```
512+
368513
<!-- tabs:end -->
369514

370515
<!-- solution:end -->

0 commit comments

Comments
 (0)