Skip to content

feat: update solutions to lc problems: No.0903~0910 #2432

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

Merged
merged 1 commit into from
Mar 11, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -73,8 +73,6 @@

时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 是字符串的长度。

我们可以用前缀和优化时间复杂度,使得时间复杂度降低到 $O(n^2)$。另外,我们也可以用滚动数组优化空间复杂度,使得空间复杂度降低到 $O(n)$。

<!-- tabs:start -->

```python
@@ -224,7 +222,7 @@ function numPermsDISequence(s: string): number {

<!-- tabs:end -->

### 方法二
我们可以用前缀和优化时间复杂度,使得时间复杂度降低到 $O(n^2)$。

<!-- tabs:start -->

@@ -372,7 +370,7 @@ function numPermsDISequence(s: string): number {

<!-- tabs:end -->

### 方法三
另外,我们也可以用滚动数组优化空间复杂度,使得空间复杂度降低到 $O(n)$。

<!-- tabs:start -->

Original file line number Diff line number Diff line change
@@ -68,8 +68,6 @@ The final answer is $\sum_{j=0}^n f[n][j]$.

The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string.

We can optimize the time complexity to $O(n^2)$ using prefix sums. Additionally, we can optimize the space complexity to $O(n)$ using a rolling array.

<!-- tabs:start -->

```python
@@ -219,7 +217,7 @@ function numPermsDISequence(s: string): number {

<!-- tabs:end -->

### Solution 2
We can optimize the time complexity to $O(n^2)$ using prefix sums.

<!-- tabs:start -->

@@ -367,7 +365,7 @@ function numPermsDISequence(s: string): number {

<!-- tabs:end -->

### Solution 3
Additionally, we can optimize the space complexity to $O(n)$ using a rolling array.

<!-- tabs:start -->

4 changes: 2 additions & 2 deletions solution/0900-0999/0904.Fruit Into Baskets/README.md
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ j i
j i
```

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `fruits` 的长度。
时间复杂度 $O(n)$,其中 $n$ 为数组 `fruits` 的长度。空间复杂度 $O(1)$

<!-- tabs:start -->

@@ -231,7 +231,7 @@ impl Solution {

但本题实际上求的是水果的最大数目,也就是“最大”的窗口,我们没有必要缩小窗口,只需要让窗口单调增大。于是代码就少了每次更新答案的操作,只需要在遍历结束后将此时的窗口大小作为答案返回即可。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `fruits` 的长度。
时间复杂度 $O(n)$,其中 $n$ 为数组 `fruits` 的长度。空间复杂度 $O(1)$

<!-- tabs:start -->

57 changes: 0 additions & 57 deletions solution/0900-0999/0907.Sum of Subarray Minimums/README.md
Original file line number Diff line number Diff line change
@@ -300,61 +300,4 @@ impl Solution {

<!-- tabs:end -->

### 方法二

<!-- tabs:start -->

```rust
const MOD: i64 = (1e9 as i64) + 7;

impl Solution {
pub fn sum_subarray_mins(arr: Vec<i32>) -> i32 {
let n: usize = arr.len();
let mut ret: i64 = 0;
let mut left: Vec<i32> = vec![-1; n];
let mut right: Vec<i32> = vec![n as i32; n];
// Index stack, store the index of the value in the given array
let mut stack: Vec<i32> = Vec::new();

// Find the first element that's less than the current value for the left side
// The default value of which is -1
for i in 0..n {
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] >= arr[i] {
stack.pop();
}
if !stack.is_empty() {
left[i] = *stack.last().unwrap();
}
stack.push(i as i32);
}

stack.clear();

// Find the first element that's less or equal than the current value for the right side
// The default value of which is n
for i in (0..n).rev() {
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] > arr[i] {
stack.pop();
}
if !stack.is_empty() {
right[i] = *stack.last().unwrap();
}
stack.push(i as i32);
}

// Traverse the array, to find the sum
for i in 0..n {
ret +=
((((right[i] - (i as i32)) * ((i as i32) - left[i])) as i64) * (arr[i] as i64)) %
MOD;
ret %= MOD;
}

(ret % (MOD as i64)) as i32
}
}
```

<!-- tabs:end -->

<!-- end -->
89 changes: 31 additions & 58 deletions solution/0900-0999/0907.Sum of Subarray Minimums/README_EN.md
Original file line number Diff line number Diff line change
@@ -37,7 +37,37 @@ Sum is 17.

## Solutions

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

The problem asks for the sum of the minimum values of each subarray, which is equivalent to finding the number of subarrays for which each element $arr[i]$ is the minimum, then multiplying by $arr[i]$, and finally summing these up.

Therefore, the focus of the problem is to find the number of subarrays for which $arr[i]$ is the minimum. For $arr[i]$, we find the first position $left[i]$ to its left that is less than $arr[i]$, and the first position $right[i]$ to its right that is less than or equal to $arr[i]$. The number of subarrays for which $arr[i]$ is the minimum is $(i - left[i]) \times (right[i] - i)$.

Note, why do we find the first position $right[i]$ to the right that is less than or equal to $arr[i]$, rather than less than $arr[i]$? This is because if we find the first position $right[i]$ to the right that is less than $arr[i]$, it will lead to duplicate calculations.

Let's take an example to illustrate. For the following array:

The element at index $3$ is $2$, the first element to its left that is less than $2$ is at index $0$. If we find the first element to its right that is less than $2$, we get index $7$. That is, the subarray interval is $(0, 7)$. Note that this is an open interval.

```
0 4 3 2 5 3 2 1
* ^ *
```

In the same way, we can find the subarray interval for the element at index $6$, and find that its subarray interval is also $(0, 7)$. That is, the subarray intervals for the elements at index $3$ and index $6$ are the same. This leads to duplicate calculations.

```
0 4 3 2 5 3 2 1
* ^ *
```

If we find the first element to its right that is less than or equal to its value, there will be no duplication, because the subarray interval for the element at index $3$ becomes $(0, 6)$, and the subarray interval for the element at index $6$ is $(0, 7)$, which are not the same.

Back to this problem, we just need to traverse the array, for each element $arr[i]$, use a monotonic stack to find the first position $left[i]$ to its left that is less than $arr[i]$, and the first position $right[i]$ to its right that is less than or equal to $arr[i]$. The number of subarrays for which $arr[i]$ is the minimum is $(i - left[i]) \times (right[i] - i)$, then multiply by $arr[i]$, and finally sum these up.

Be aware of data overflow and modulo operations.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $arr$.

<!-- tabs:start -->

@@ -264,61 +294,4 @@ impl Solution {

<!-- tabs:end -->

### Solution 2

<!-- tabs:start -->

```rust
const MOD: i64 = (1e9 as i64) + 7;

impl Solution {
pub fn sum_subarray_mins(arr: Vec<i32>) -> i32 {
let n: usize = arr.len();
let mut ret: i64 = 0;
let mut left: Vec<i32> = vec![-1; n];
let mut right: Vec<i32> = vec![n as i32; n];
// Index stack, store the index of the value in the given array
let mut stack: Vec<i32> = Vec::new();

// Find the first element that's less than the current value for the left side
// The default value of which is -1
for i in 0..n {
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] >= arr[i] {
stack.pop();
}
if !stack.is_empty() {
left[i] = *stack.last().unwrap();
}
stack.push(i as i32);
}

stack.clear();

// Find the first element that's less or equal than the current value for the right side
// The default value of which is n
for i in (0..n).rev() {
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] > arr[i] {
stack.pop();
}
if !stack.is_empty() {
right[i] = *stack.last().unwrap();
}
stack.push(i as i32);
}

// Traverse the array, to find the sum
for i in 0..n {
ret +=
((((right[i] - (i as i32)) * ((i as i32) - left[i])) as i64) * (arr[i] as i64)) %
MOD;
ret %= MOD;
}

(ret % (MOD as i64)) as i32
}
}
```

<!-- tabs:end -->

<!-- end -->
48 changes: 0 additions & 48 deletions solution/0900-0999/0907.Sum of Subarray Minimums/Solution2.rs

This file was deleted.

8 changes: 7 additions & 1 deletion solution/0900-0999/0908.Smallest Range I/README.md
Original file line number Diff line number Diff line change
@@ -54,7 +54,13 @@

## 解法

### 方法一
### 方法一:数学

根据题目描述,我们可以将数组中的最大值加上 $k$,最小值减去 $k$,这样可以使得数组中的最大值和最小值之差变小。

因此,最终的答案就是 $\max(nums) - \min(nums) - 2 \times k$。

时间复杂度 $O(n)$,其中 $n$ 为数组 `nums` 的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

8 changes: 7 additions & 1 deletion solution/0900-0999/0908.Smallest Range I/README_EN.md
Original file line number Diff line number Diff line change
@@ -50,7 +50,13 @@

## Solutions

### Solution 1
### Solution 1: Mathematics

According to the problem description, we can add $k$ to the maximum value in the array and subtract $k$ from the minimum value. This can reduce the difference between the maximum and minimum values in the array.

Therefore, the final answer is $\max(nums) - \min(nums) - 2 \times k$.

The time complexity is $O(n)$, where $n$ is the length of the array `nums`. The space complexity is $O(1)$.

<!-- tabs:start -->

8 changes: 7 additions & 1 deletion solution/0900-0999/0910.Smallest Range II/README_EN.md
Original file line number Diff line number Diff line change
@@ -50,7 +50,13 @@

## Solutions

### Solution 1
### Solution 1: Greedy + Enumeration

According to the problem requirements, we need to find the minimum difference between the maximum and minimum values in the array. Each element can be increased or decreased by $k$, so we can divide the elements in the array into two parts, one part increased by $k$ and the other part decreased by $k$. Therefore, we should decrease the larger values in the array by $k$ and increase the smaller values by $k$ to ensure the minimum difference between the maximum and minimum values.

Therefore, we can first sort the array, then enumerate each element in the array, divide it into two parts, one part increased by $k$ and the other part decreased by $k$, and calculate the difference between the maximum and minimum values. Finally, take the minimum value among all differences.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$, where $n$ is the length of the array.

<!-- tabs:start -->