Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 182fba7

Browse files
feat: add solutions to lc problem: No.2106 (doocs#4614)
No.2106.Maximum Fruits Harvested After at Most K Steps
1 parent 7bb3abb commit 182fba7

File tree

3 files changed

+102
-11
lines changed

3 files changed

+102
-11
lines changed

‎solution/2100-2199/2106.Maximum Fruits Harvested After at Most K Steps/README.md‎

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,24 @@ tags:
8383

8484
### 方法一:双指针
8585

86-
我们不妨假设移动的位置区间为 $[l,r],ドル开始位置为 $startPos,ドル来看看如何算出移动的最小步数。根据 $startPos$ 所处的位置,我们可以分为三种情况:
86+
我们不妨假设移动的位置区间为 $[l,r],ドル开始位置为 $\textit{startPos},ドル来看看如何算出移动的最小步数。根据 $\textit{startPos}$ 所处的位置,我们可以分为三种情况:
8787

88-
1. 如果 $startPos \leq l,ドル那么就是从 $startPos$ 一直向右移动到 $r$。移动的最小步数为 $r - startPos$;
89-
2. 如果 $startPos \geq r,ドル那么就是从 $startPos$ 一直向左移动到 $l$。移动的最小步数为 $startPos - l$;
90-
3. 如果 $l \lt startPos \lt r,ドル那么可以从 $startPos$ 向左移动到 $l,ドル再向右移动到 $r$;也可以从 $startPos$ 向右移动到 $r,ドル再向左移动到 $l$。移动的最小步数为 $r - l + \min(\lvert startPos - l \rvert, \lvert r - startPos \rvert)$。
88+
1. 如果 $\textit{startPos} \leq l,ドル那么就是从 $\textit{startPos}$ 一直向右移动到 $r$。移动的最小步数为 $r - \textit{startPos}$;
89+
2. 如果 $\textit{startPos} \geq r,ドル那么就是从 $\textit{startPos}$ 一直向左移动到 $l$。移动的最小步数为 $\textit{startPos} - l$;
90+
3. 如果 $l < \textit{startPos} < r,ドル那么可以从 $\textit{startPos}$ 向左移动到 $l,ドル再向右移动到 $r$;也可以从 $\textit{startPos}$ 向右移动到 $r,ドル再向左移动到 $l$。移动的最小步数为 $r - l + \min(\lvert \textit{startPos} - l \rvert, \lvert r - \textit{startPos} \rvert)$。
9191

92-
以上三种情况可以统一用式子 $r - l + \min(\lvert startPos - l \rvert, \lvert r - startPos \rvert)$ 表示。
92+
以上三种情况可以统一用式子 $r - l + \min(\lvert \textit{startPos} - l \rvert, \lvert r - \textit{startPos} \rvert)$ 表示。
9393

9494
假设我们固定区间右端点 $r,ドル向右移动左端点 $l,ドル我们来看看最小移动步数是怎么变化的。
9595

96-
1. 如果 $startPos \leq l,ドル随着 $l$ 的增大,最小步数不会发生变化。
97-
2. 如果 $startPos \gt l,ドル随着 $l$ 的增大,最小步数会减小。
96+
1. 如果 $\textit{startPos} \leq l,ドル随着 $l$ 的增大,最小步数不会发生变化。
97+
2. 如果 $\textit{startPos} > l,ドル随着 $l$ 的增大,最小步数会减小。
9898

9999
因此,随着 $l$ 的增大,最小移动步数一定是非严格单调递减的。基于此,我们可以使用双指针的方法,找出所有符合条件的最大区间,然后取所有符合条件的区间中水果总数最大的一个作为答案。
100100

101101
具体地,我们用两个指针 $i$ 和 $j$ 分别指向区间的左右下标,初始时 $i = j = 0$。另外用一个变量 $s$ 记录区间内的水果总数,初始时 $s = 0$。
102102

103-
每次我们将 $j$ 加入区间中,然后更新 $s = s + fruits[j][1]$。如果此时区间内的最小步数 $fruits[j][0] - fruits[i][0] + \min(\lvert startPos - fruits[i][0] \rvert, \lvert startPos - fruits[j][0] \rvert)$ 大于 $k,ドル那么我们就将 $i$ 循环向右移动,直到 $i \gt j$ 或者区间内的最小步数小于等于 $k$。此时我们更新答案 $ans = \max(ans, s)$。继续移动 $j,ドル直到 $j$ 到达数组末尾。
103+
每次我们将 $j$ 加入区间中,然后更新 $s = s + \textit{fruits}[j][1]$。如果此时区间内的最小步数 $\textit{fruits}[j][0] - \textit{fruits}[i][0] + \min(\lvert \textit{startPos} - \textit{fruits}[i][0] \rvert, \lvert \textit{startPos} - \textit{fruits}[j][0] \rvert)$ 大于 $k,ドル那么我们就将 $i$ 循环向右移动,直到 $i > j$ 或者区间内的最小步数小于等于 $k$。此时我们更新答案 $\textit{ans} = \max(\textit{ans}, s)$。继续移动 $j,ドル直到 $j$ 到达数组末尾。
104104

105105
最后返回答案即可。
106106

@@ -219,6 +219,29 @@ function maxTotalFruits(fruits: number[][], startPos: number, k: number): number
219219
}
220220
```
221221

222+
#### Rust
223+
224+
```rust
225+
impl Solution {
226+
pub fn max_total_fruits(fruits: Vec<Vec<i32>>, start_pos: i32, k: i32) -> i32 {
227+
let mut ans = 0;
228+
let mut s = 0;
229+
let mut i = 0;
230+
for j in 0..fruits.len() {
231+
let pj = fruits[j][0];
232+
let fj = fruits[j][1];
233+
s += fj;
234+
while i <= j && pj - fruits[i][0] + std::cmp::min((start_pos - fruits[i][0]).abs(), (start_pos - pj).abs()) > k {
235+
s -= fruits[i][1];
236+
i += 1;
237+
}
238+
ans = ans.max(s)
239+
}
240+
ans
241+
}
242+
}
243+
```
244+
222245
<!-- tabs:end -->
223246

224247
<!-- solution:end -->

‎solution/2100-2199/2106.Maximum Fruits Harvested After at Most K Steps/README_EN.md‎

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ tags:
3333
<pre>
3434
<strong>Input:</strong> fruits = [[2,8],[6,3],[8,6]], startPos = 5, k = 4
3535
<strong>Output:</strong> 9
36-
<strong>Explanation:</strong>
36+
<strong>Explanation:</strong>
3737
The optimal way is to:
3838
- Move right to position 6 and harvest 3 fruits
3939
- Move right to position 8 and harvest 6 fruits
@@ -45,7 +45,7 @@ You moved 3 steps and harvested 3 + 6 = 9 fruits in total.
4545
<pre>
4646
<strong>Input:</strong> fruits = [[0,9],[4,1],[5,7],[6,2],[7,4],[10,9]], startPos = 5, k = 4
4747
<strong>Output:</strong> 14
48-
<strong>Explanation:</strong>
48+
<strong>Explanation:</strong>
4949
You can move at most k = 4 steps, so you cannot reach position 0 nor 10.
5050
The optimal way is to:
5151
- Harvest the 7 fruits at the starting position 5
@@ -82,7 +82,30 @@ You can move at most k = 2 steps and cannot reach any position with fruits.
8282

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

85-
### Solution 1
85+
### Solution 1: Two Pointers
86+
87+
Let's assume the movement range is $[l, r]$ and the starting position is $\textit{startPos}$. We need to calculate the minimum number of steps required. Based on the position of $\textit{startPos},ドル we can divide this into three cases:
88+
89+
1. If $\textit{startPos} \leq l,ドル then we move right from $\textit{startPos}$ to $r$. The minimum number of steps is $r - \textit{startPos}$;
90+
2. If $\textit{startPos} \geq r,ドル then we move left from $\textit{startPos}$ to $l$. The minimum number of steps is $\textit{startPos} - l$;
91+
3. If $l < \textit{startPos} < r,ドル we can either move left from $\textit{startPos}$ to $l$ then right to $r,ドル or move right from $\textit{startPos}$ to $r$ then left to $l$. The minimum number of steps is $r - l + \min(\lvert \textit{startPos} - l \rvert, \lvert r - \textit{startPos} \rvert)$.
92+
93+
All three cases can be unified by the formula $r - l + \min(\lvert \textit{startPos} - l \rvert, \lvert r - \textit{startPos} \rvert)$.
94+
95+
Suppose we fix the right endpoint $r$ of the interval and move the left endpoint $l$ to the right. Let's see how the minimum number of steps changes:
96+
97+
1. If $\textit{startPos} \leq l,ドル as $l$ increases, the minimum number of steps remains unchanged.
98+
2. If $\textit{startPos} > l,ドル as $l$ increases, the minimum number of steps decreases.
99+
100+
Therefore, as $l$ increases, the minimum number of steps is non-strictly monotonically decreasing. Based on this, we can use the two-pointer approach to find all qualifying maximum intervals, then take the one with the maximum total fruits among all qualifying intervals as the answer.
101+
102+
Specifically, we use two pointers $i$ and $j$ to point to the left and right indices of the interval, initially $i = j = 0$. We also use a variable $s$ to record the total number of fruits in the interval, initially $s = 0$.
103+
104+
Each time we include $j$ in the interval, then update $s = s + \textit{fruits}[j][1]$. If the minimum number of steps in the current interval $\textit{fruits}[j][0] - \textit{fruits}[i][0] + \min(\lvert \textit{startPos} - \textit{fruits}[i][0] \rvert, \lvert \textit{startPos} - \textit{fruits}[j][0] \rvert)$ is greater than $k,ドル we move $i$ to the right in a loop until $i > j$ or the minimum number of steps in the interval is less than or equal to $k$. At this point, we update the answer $\textit{ans} = \max(\textit{ans}, s)$. Continue moving $j$ until $j$ reaches the end of the array.
105+
106+
Finally, return the answer.
107+
108+
The time complexity is $O(n),ドル where $n$ is the length of the array. The space complexity is $O(1)$.
86109

87110
<!-- tabs:start -->
88111

@@ -197,6 +220,29 @@ function maxTotalFruits(fruits: number[][], startPos: number, k: number): number
197220
}
198221
```
199222

223+
#### Rust
224+
225+
```rust
226+
impl Solution {
227+
pub fn max_total_fruits(fruits: Vec<Vec<i32>>, start_pos: i32, k: i32) -> i32 {
228+
let mut ans = 0;
229+
let mut s = 0;
230+
let mut i = 0;
231+
for j in 0..fruits.len() {
232+
let pj = fruits[j][0];
233+
let fj = fruits[j][1];
234+
s += fj;
235+
while i <= j && pj - fruits[i][0] + std::cmp::min((start_pos - fruits[i][0]).abs(), (start_pos - pj).abs()) > k {
236+
s -= fruits[i][1];
237+
i += 1;
238+
}
239+
ans = ans.max(s)
240+
}
241+
ans
242+
}
243+
}
244+
```
245+
200246
<!-- tabs:end -->
201247

202248
<!-- solution:end -->
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
impl Solution {
2+
pub fn max_total_fruits(fruits: Vec<Vec<i32>>, start_pos: i32, k: i32) -> i32 {
3+
let mut ans = 0;
4+
let mut s = 0;
5+
let mut i = 0;
6+
for j in 0..fruits.len() {
7+
let pj = fruits[j][0];
8+
let fj = fruits[j][1];
9+
s += fj;
10+
while i <= j
11+
&& pj - fruits[i][0]
12+
+ std::cmp::min((start_pos - fruits[i][0]).abs(), (start_pos - pj).abs())
13+
> k
14+
{
15+
s -= fruits[i][1];
16+
i += 1;
17+
}
18+
ans = ans.max(s)
19+
}
20+
ans
21+
}
22+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /