Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update lc problems #4106

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions solution/0700-0799/0763.Partition Labels/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ tags:

### 方法一:贪心

我们先用数组或哈希表 $last$ 记录字符串 $s$ 中每个字母最后一次出现的位置。
我们先用数组或哈希表 $\textit{last}$ 记录字符串 $s$ 中每个字母最后一次出现的位置。

接下来我们使用贪心的方法,将字符串划分为尽可能多的片段。

从左到右遍历字符串 $s$,遍历的同时维护当前片段的开始下标 $j$ 和结束下标 $i$,初始均为 $0$。

对于每个访问到的字母 $c$,获取到最后一次出现的位置 $last[c]$。由于当前片段的结束下标一定不会小于 $last[c]$,因此令 $mx = \max(mx, last[c])$。
对于每个访问到的字母 $c$,获取到最后一次出现的位置 $\textit{last}[c]$。由于当前片段的结束下标一定不会小于 $\textit{last}[c]$,因此令 $\textit{mx} = \max(\textit{mx}, \textit{last}[c])$。

当访问到下标 $mx$ 时,意味着当前片段访问结束,当前片段的下标范围是 $[j,.. i]$,长度为 $i - j + 1$,我们将其添加到结果数组中。然后令 $j = i + 1$, 继续寻找下一个片段。
当访问到下标 $\textit{mx}$ 时,意味着当前片段访问结束,当前片段的下标范围是 $[j,.. i]$,长度为 $i - j + 1$,我们将其添加到结果数组中。然后令 $j = i + 1$, 继续寻找下一个片段。

重复上述过程,直至字符串遍历结束,即可得到所有片段的长度。

时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $s$ 的长度,而 $C$ 为字符集的大小。本题中 $C = 26$。
时间复杂度 $O(n)$,空间复杂度 $O(|\Sigma|)$。其中 $n$ 为字符串 $s$ 的长度,而 $|\Sigma|$ 为字符集的大小。本题中 $|\Sigma| = 26$。

<!-- tabs:start -->

Expand Down
16 changes: 15 additions & 1 deletion solution/0700-0799/0763.Partition Labels/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,21 @@ A partition like &quot;ababcbacadefegde&quot;, &quot;hijhklij&quot; is incorrect

<!-- solution:start -->

### Solution 1
### Solution 1: Greedy

We first use an array or hash table $\textit{last}$ to record the last occurrence of each letter in the string $s$.

Next, we use a greedy approach to partition the string into as many segments as possible.

Traverse the string $s$ from left to right, while maintaining the start index $j$ and end index $i$ of the current segment, both initially set to $0$.

For each letter $c$ visited, get the last occurrence position $\textit{last}[c]$. Since the end index of the current segment must not be less than $\textit{last}[c]$, let $\textit{mx} = \max(\textit{mx}, \textit{last}[c])$.

When visiting the index $\textit{mx}$, it means the current segment ends. The index range of the current segment is $[j,.. i]$, and the length is $i - j + 1$. We add this length to the result array. Then set $j = i + 1$ and continue to find the next segment.

Repeat the above process until the string traversal is complete to get the lengths of all segments.

Time complexity is $O(n)$, and space complexity is $O(|\Sigma|)$. Where $n$ is the length of the string $s$, and $|\Sigma|$ is the size of the character set. In this problem, $|\Sigma| = 26$.

<!-- tabs:start -->

Expand Down
12 changes: 11 additions & 1 deletion solution/0700-0799/0765.Couples Holding Hands/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,17 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Union-Find

We can assign a number to each pair of couples. Person with number $0$ and $1$ corresponds to couple $0$, person with number $2$ and $3$ corresponds to couple $1$, and so on. In other words, the person corresponding to $row[i]$ has a couple number of $\lfloor \frac{row[i]}{2} \rfloor$.

If there are $k$ pairs of couples who are seated incorrectly with respect to each other, i.e., if $k$ pairs of couples are in the same permutation cycle, it will take $k-1$ swaps for all of them to be seated correctly.

Why? Consider the following: we first adjust the positions of a couple to their correct seats. After this, the problem reduces from $k$ couples to $k-1$ couples. This process continues, and when $k = 1$, the number of swaps required is $0$. Therefore, if $k$ pairs of couples are in the wrong positions, we need $k-1$ swaps.

Thus, we only need to traverse the array once, use union-find to determine how many permutation cycles there are. Suppose there are $x$ cycles, and the size of each cycle (in terms of couple pairs) is $y_1, y_2, \cdots, y_x$. The number of swaps required is $y_1-1 + y_2-1 + \cdots + y_x-1 = y_1 + y_2 + \cdots + y_x - x = n - x$.

The time complexity is $O(n \times \alpha(n))$, and the space complexity is $O(n)$, where $\alpha(n)$ is the inverse Ackermann function, which can be considered a very small constant.

<!-- tabs:start -->

Expand Down
54 changes: 29 additions & 25 deletions solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ tags:
<strong>输入:</strong>arr = [5,4,3,2,1]
<strong>输出:</strong>1
<strong>解释:</strong>
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
</pre>

<p><strong class="example">示例 2:</strong></p>
Expand All @@ -43,8 +43,8 @@ tags:
<strong>输入:</strong>arr = [2,1,3,4,4]
<strong>输出:</strong>4
<strong>解释:</strong>
可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
</pre>

<p>&nbsp;</p>
Expand All @@ -66,7 +66,7 @@ tags:

根据题目,我们可以发现,从左到右,每个分块都有一个最大值,并且这些分块的最大值呈单调递增(非严格递增)。我们可以用一个栈来存储这些分块的最大值。最后得到的栈的大小,也就是题目所求的最多能完成排序的块。

时间复杂度 $O(n)$,其中 $n$ 表示 $arr$ 的长度。
时间复杂度 $O(n)$,其中 $n$ 表示 $\textit{arr}$ 的长度。

<!-- tabs:start -->

Expand Down Expand Up @@ -156,19 +156,19 @@ func maxChunksToSorted(arr []int) int {

```ts
function maxChunksToSorted(arr: number[]): number {
const stack = [];
for (const num of arr) {
if (stack.length !== 0 && num < stack[stack.length - 1]) {
const max = stack.pop();
while (stack.length !== 0 && num < stack[stack.length - 1]) {
stack.pop();
}
stack.push(max);
const stk: number[] = [];
for (let v of arr) {
if (stk.length === 0 || v >= stk[stk.length - 1]) {
stk.push(v);
} else {
stack.push(num);
let mx = stk.pop()!;
while (stk.length > 0 && stk[stk.length - 1] > v) {
stk.pop();
}
stk.push(mx);
}
}
return stack.length;
return stk.length;
}
```

Expand All @@ -177,19 +177,23 @@ function maxChunksToSorted(arr: number[]): number {
```rust
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut stack = vec![];
for num in arr.iter() {
if !stack.is_empty() && num < stack.last().unwrap() {
let max = stack.pop().unwrap();
while !stack.is_empty() && num < stack.last().unwrap() {
stack.pop();
}
stack.push(max);
let mut stk = Vec::new();
for &v in arr.iter() {
if stk.is_empty() || v >= *stk.last().unwrap() {
stk.push(v);
} else {
stack.push(*num);
let mut mx = stk.pop().unwrap();
while let Some(&top) = stk.last() {
if top > v {
stk.pop();
} else {
break;
}
}
stk.push(mx);
}
}
stack.len() as i32
stk.len() as i32
}
}
```
Expand Down
50 changes: 29 additions & 21 deletions solution/0700-0799/0768.Max Chunks To Make Sorted II/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ However, splitting into [2, 1], [3], [4], [4] is the highest number of chunks po

<!-- solution:start -->

### Solution 1
### Solution 1: Monotonic Stack

According to the problem, we can find that from left to right, each chunk has a maximum value, and these maximum values are monotonically increasing (non-strictly increasing). We can use a stack to store these maximum values of the chunks. The size of the final stack is the maximum number of chunks that can be sorted.

Time complexity is $O(n)$, where $n$ represents the length of $\textit{arr}$.

<!-- tabs:start -->

Expand Down Expand Up @@ -151,19 +155,19 @@ func maxChunksToSorted(arr []int) int {

```ts
function maxChunksToSorted(arr: number[]): number {
const stack = [];
for (const num of arr) {
if (stack.length !== 0 && num < stack[stack.length - 1]) {
const max = stack.pop();
while (stack.length !== 0 && num < stack[stack.length - 1]) {
stack.pop();
}
stack.push(max);
const stk: number[] = [];
for (let v of arr) {
if (stk.length === 0 || v >= stk[stk.length - 1]) {
stk.push(v);
} else {
stack.push(num);
let mx = stk.pop()!;
while (stk.length > 0 && stk[stk.length - 1] > v) {
stk.pop();
}
stk.push(mx);
}
}
return stack.length;
return stk.length;
}
```

Expand All @@ -172,19 +176,23 @@ function maxChunksToSorted(arr: number[]): number {
```rust
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut stack = vec![];
for num in arr.iter() {
if !stack.is_empty() && num < stack.last().unwrap() {
let max = stack.pop().unwrap();
while !stack.is_empty() && num < stack.last().unwrap() {
stack.pop();
}
stack.push(max);
let mut stk = Vec::new();
for &v in arr.iter() {
if stk.is_empty() || v >= *stk.last().unwrap() {
stk.push(v);
} else {
stack.push(*num);
let mut mx = stk.pop().unwrap();
while let Some(&top) = stk.last() {
if top > v {
stk.pop();
} else {
break;
}
}
stk.push(mx);
}
}
stack.len() as i32
stk.len() as i32
}
}
```
Expand Down
24 changes: 14 additions & 10 deletions solution/0700-0799/0768.Max Chunks To Make Sorted II/Solution.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut stack = vec![];
for num in arr.iter() {
if !stack.is_empty() && num < stack.last().unwrap() {
let max = stack.pop().unwrap();
while !stack.is_empty() && num < stack.last().unwrap() {
stack.pop();
}
stack.push(max);
let mut stk = Vec::new();
for &v in arr.iter() {
if stk.is_empty() || v >= *stk.last().unwrap() {
stk.push(v);
} else {
stack.push(*num);
let mut mx = stk.pop().unwrap();
while let Some(&top) = stk.last() {
if top > v {
stk.pop();
} else {
break;
}
}
stk.push(mx);
}
}
stack.len() as i32
stk.len() as i32
}
}
20 changes: 10 additions & 10 deletions solution/0700-0799/0768.Max Chunks To Make Sorted II/Solution.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
function maxChunksToSorted(arr: number[]): number {
const stack = [];
for (const num of arr) {
if (stack.length !== 0 && num < stack[stack.length - 1]) {
const max = stack.pop();
while (stack.length !== 0 && num < stack[stack.length - 1]) {
stack.pop();
}
stack.push(max);
const stk: number[] = [];
for (let v of arr) {
if (stk.length === 0 || v >= stk[stk.length - 1]) {
stk.push(v);
} else {
stack.push(num);
let mx = stk.pop()!;
while (stk.length > 0 && stk[stk.length - 1] > v) {
stk.pop();
}
stk.push(mx);
}
}
return stack.length;
return stk.length;
}
30 changes: 15 additions & 15 deletions solution/0700-0799/0769.Max Chunks To Make Sorted/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ tags:

### 方法一:贪心 + 一次遍历

由于 $arr$ 是 $[0,..,n-1]$ 的一个排列,若已遍历过的数中的最大值 $mx$ 与当前遍历到的下标 $i$ 相等,说明可以进行一次分割,累加答案。
由于 $\textit{arr}$ 是 $[0,..,n-1]$ 的一个排列,若已遍历过的数中的最大值 $\textit{mx}$ 与当前遍历到的下标 $i$ 相等,说明可以进行一次分割,累加答案。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $arr$ 的长度。
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $\textit{arr}$ 的长度。

<!-- tabs:start -->

Expand Down Expand Up @@ -141,10 +141,10 @@ func maxChunksToSorted(arr []int) int {
function maxChunksToSorted(arr: number[]): number {
const n = arr.length;
let ans = 0;
let max = 0;
let mx = 0;
for (let i = 0; i < n; i++) {
max = Math.max(arr[i], max);
if (max == i) {
mx = Math.max(arr[i], mx);
if (mx == i) {
ans++;
}
}
Expand All @@ -157,15 +157,15 @@ function maxChunksToSorted(arr: number[]): number {
```rust
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut res = 0;
let mut max = 0;
let mut ans = 0;
let mut mx = 0;
for i in 0..arr.len() {
max = max.max(arr[i]);
if max == (i as i32) {
res += 1;
mx = mx.max(arr[i]);
if mx == (i as i32) {
ans += 1;
}
}
res
ans
}
}
```
Expand All @@ -176,15 +176,15 @@ impl Solution {
#define max(a, b) (((a) > (b)) ? (a) : (b))

int maxChunksToSorted(int* arr, int arrSize) {
int res = 0;
int ans = 0;
int mx = -1;
for (int i = 0; i < arrSize; i++) {
mx = max(mx, arr[i]);
if (mx == i) {
res++;
ans++;
}
}
return res;
return ans;
}
```

Expand All @@ -202,7 +202,7 @@ int maxChunksToSorted(int* arr, int arrSize) {

以上这种解法,不仅可以解决本题,也可以解决 [768. 最多能完成排序的块 II](https://github.com/doocs/leetcode/blob/main/solution/0700-0799/0768.Max%20Chunks%20To%20Make%20Sorted%20II/README.md) 这道困难题。大家可以自行尝试。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $arr$ 的长度。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{arr}$ 的长度。

<!-- tabs:start -->

Expand Down
Loading