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 b124152

Browse files
authored
Merge branch 'youngyangyang04:master' into master
2 parents c835ec0 + f979407 commit b124152

File tree

70 files changed

+1314
-837
lines changed

Some content is hidden

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

70 files changed

+1314
-837
lines changed

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
如果你是算法老手,这篇攻略也是复习的最佳资料,如果把每个系列对应的总结篇,快速过一遍,整个算法知识体系以及各种解法就重现脑海了。
6363

6464

65-
目前「代码随想录」刷题攻略更新了:**200多篇文章,精讲了200道经典算法题目,共60w字的详细图解,部分难点题目还搭配了20分钟左右的视频讲解**
65+
目前「代码随想录」刷题攻略更新了:**200多篇文章,精讲了200道经典算法题目,共60w字的详细图解,大部分题目都搭配了20分钟左右的视频讲解**,视频质量很好,口碑很好,大家可以去看看,视频列表:[代码随想录视频讲解](https://www.bilibili.com/video/BV1fA4y1o715)
6666

6767
**这里每一篇题解,都是精品,值得仔细琢磨**
6868

‎problems/0001.两数之和.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,26 @@ impl Solution {
216216
}
217217
}
218218
```
219+
Rust
220+
221+
```
222+
use std::collections::HashMap;
223+
224+
impl Solution {
225+
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
226+
let mut hm: HashMap<i32, i32> = HashMap::new();
227+
for i in 0..nums.len() {
228+
let j = target - nums[i];
229+
if hm.contains_key(&j) {
230+
return vec![*hm.get(&j).unwrap(), i as i32]
231+
} else {
232+
hm.insert(nums[i], i as i32);
233+
}
234+
}
235+
vec![-1, -1]
236+
}
237+
}
238+
```
219239

220240
Javascript
221241

‎problems/0020.有效的括号.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ public:
135135
};
136136

137137
```
138+
* 时间复杂度: O(n)
139+
* 空间复杂度: O(n)
140+
138141
技巧性的东西没有固定的学习方法,还是要多看多练,自己灵活运用了。
139142
140143

‎problems/0045.跳跃游戏II.md‎

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
</a>
55
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
66

7+
> 相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不少,做好心里准备!
78
8-
> 相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不少,做好心里准备!
9-
10-
# 45.跳跃游戏II
9+
# 45.跳跃游戏 II
1110

1211
[力扣题目链接](https://leetcode.cn/problems/jump-game-ii/)
1312

@@ -18,13 +17,17 @@
1817
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
1918

2019
示例:
21-
* 输入: [2,3,1,1,4]
22-
* 输出: 2
23-
* 解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
20+
21+
- 输入: [2,3,1,1,4]
22+
- 输出: 2
23+
- 解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
2424

2525
说明:
2626
假设你总是可以到达数组的最后一个位置。
2727

28+
# 视频讲解
29+
30+
**《代码随想录》算法视频公开课:[贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏 II](https://www.bilibili.com/video/BV1Y24y1r7XZ),相信结合视频在看本篇题解,更有助于大家对本题的理解**
2831

2932
## 思路
3033

@@ -46,7 +49,6 @@
4649

4750
如图:
4851

49-
5052
![45.跳跃游戏II](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232309103.png)
5153

5254
**图中覆盖范围的意义在于,只要红色的区域,最多两步一定可以到!(不用管具体怎么跳,反正一定可以跳到)**
@@ -57,8 +59,8 @@
5759

5860
这里还是有个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时
5961

60-
* 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
61-
* 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
62+
- 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
63+
- 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
6264

6365
C++代码如下:(详细注释)
6466

@@ -74,32 +76,34 @@ public:
7476
for (int i = 0; i < nums.size(); i++) {
7577
nextDistance = max(nums[i] + i, nextDistance); // 更新下一步覆盖最远距离下标
7678
if (i == curDistance) { // 遇到当前覆盖最远距离下标
77-
if (curDistance < nums.size() - 1) { // 如果当前覆盖最远距离下标不是终点
78-
ans++; // 需要走下一步
79-
curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了)
80-
if (nextDistance >= nums.size() - 1) break; // 下一步的覆盖范围已经可以达到终点,结束循环
81-
} else break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束
79+
ans++; // 需要走下一步
80+
curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了)
81+
if (nextDistance >= nums.size() - 1) break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束
8282
}
8383
}
8484
return ans;
8585
}
8686
};
8787
```
8888
89+
* 时间复杂度: O(n)
90+
* 空间复杂度: O(1)
91+
92+
8993
## 方法二
9094
9195
依然是贪心,思路和方法一差不多,代码可以简洁一些。
9296
9397
**针对于方法一的特殊情况,可以统一处理**,即:移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不考虑是不是终点的情况。
9498
95-
想要达到这样的效果,只要让移动下标,最大只能移动到nums.size - 2的地方就可以了
99+
想要达到这样的效果,只要让移动下标,最大只能移动到 nums.size - 2 的地方就可以了
96100
97-
因为当移动下标指向nums.size - 2时:
101+
因为当移动下标指向 nums.size - 2 时:
98102
99-
* 如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即ans++),因为最后一步一定是可以到的终点。(题目假设总是可以到达数组的最后一个位置),如图:
100-
![45.跳跃游戏II2](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232445286.png)
103+
- 如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即 ans++),因为最后一步一定是可以到的终点。(题目假设总是可以到达数组的最后一个位置),如图:
104+
![45.跳跃游戏II2](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232445286.png)
101105
102-
* 如果移动下标不等于当前覆盖最大距离下标,说明当前覆盖最远距离就可以直接达到终点了,不需要再走一步。如图:
106+
- 如果移动下标不等于当前覆盖最大距离下标,说明当前覆盖最远距离就可以直接达到终点了,不需要再走一步。如图:
103107
104108
![45.跳跃游戏II1](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232338693.png)
105109
@@ -125,9 +129,14 @@ public:
125129
};
126130
```
127131

132+
* 时间复杂度: O(n)
133+
* 空间复杂度: O(1)
134+
135+
136+
128137
可以看出版本二的代码相对于版本一简化了不少!
129138

130-
**其精髓在于控制移动下标i只移动到nums.size() - 2的位置**,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。
139+
**其精髓在于控制移动下标 i 只移动到 nums.size() - 2 的位置**,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。
131140

132141
## 总结
133142

@@ -137,11 +146,10 @@ public:
137146

138147
理解本题的关键在于:**以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点**,这个范围内最小步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。
139148

140-
141149
## 其他语言版本
142150

151+
### Java
143152

144-
### Java
145153
```Java
146154
// 版本一
147155
class Solution {
@@ -207,7 +215,7 @@ class Solution:
207215
nextDistance = 0
208216
for i in range(len(nums)):
209217
nextDistance = max(i + nums[i], nextDistance)
210-
if i == curDistance:
218+
if i == curDistance:
211219
if curDistance != len(nums) - 1:
212220
ans += 1
213221
curDistance = nextDistance
@@ -230,9 +238,25 @@ class Solution:
230238
step += 1
231239
return step
232240
```
241+
```python
242+
# 贪心版本三 - 类似‘55-跳跃游戏’写法
243+
class Solution:
244+
def jump(self, nums) -> int:
245+
if len(nums)==1: return 0
246+
i = 0
247+
count = 0
248+
cover = 0
249+
while i<=cover:
250+
for i in range(i,cover+1):
251+
cover = max(nums[i]+i,cover)
252+
if cover>=len(nums)-1: return count+1
253+
count+=1
254+
255+
```
256+
233257
```python
234258
# 动态规划做法
235-
class Solution:
259+
class Solution:
236260
def jump(self, nums: List[int]) -> int:
237261
result = [10**4+1]*len(nums)
238262
result[0]=0
@@ -244,7 +268,6 @@ class Solution:
244268

245269
```
246270

247-
248271
### Go
249272

250273
```go
@@ -331,21 +354,21 @@ var jump = function(nums) {
331354

332355
```typescript
333356
function jump(nums: number[]): number {
334-
const length: number = nums.length;
335-
let curFarthestIndex: number = 0,
336-
nextFarthestIndex: number = 0;
337-
let curIndex: number = 0;
338-
let stepNum: number = 0;
339-
while (curIndex < length - 1) {
340-
nextFarthestIndex = Math.max(nextFarthestIndex, curIndex + nums[curIndex]);
341-
if (curIndex === curFarthestIndex) {
342-
curFarthestIndex = nextFarthestIndex;
343-
stepNum++;
344-
}
345-
curIndex++;
357+
const length: number = nums.length;
358+
let curFarthestIndex: number = 0,
359+
nextFarthestIndex: number = 0;
360+
let curIndex: number = 0;
361+
let stepNum: number = 0;
362+
while (curIndex < length - 1) {
363+
nextFarthestIndex = Math.max(nextFarthestIndex, curIndex + nums[curIndex]);
364+
if (curIndex === curFarthestIndex) {
365+
curFarthestIndex = nextFarthestIndex;
366+
stepNum++;
346367
}
347-
return stepNum;
348-
};
368+
curIndex++;
369+
}
370+
return stepNum;
371+
}
349372
```
350373

351374
### Scala
@@ -427,7 +450,6 @@ impl Solution {
427450
}
428451
```
429452

430-
431453
<p align="center">
432454
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
433455
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

‎problems/0047.全排列II.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,19 @@ if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
158158

159159
所以我通过举[1,1,1]的例子,把这两个去重的逻辑分别抽象成树形结构,大家可以一目了然:为什么两种写法都可以以及哪一种效率更高!
160160

161+
这里可能大家又有疑惑,既然 `used[i - 1] == false`也行而`used[i - 1] == true`也行,那为什么还要写这个条件呢?
162+
163+
直接这样写 不就完事了?
164+
165+
```cpp
166+
if (i > 0 && nums[i] == nums[i - 1]) {
167+
continue;
168+
}
169+
```
170+
171+
其实并不行,一定要加上 `used[i - 1] == false`或者`used[i - 1] == true`,因为 used[i - 1] 要一直是 true 或者一直是false 才可以,而不是 一会是true 一会又是false。 所以这个条件要写上。
172+
173+
161174
是不是豁然开朗了!!
162175

163176
## 其他语言版本

0 commit comments

Comments
(0)

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