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 e6a205d

Browse files
Merge branch 'youngyangyang04:master' into master
2 parents 05fc5cb + fbe1e00 commit e6a205d

File tree

258 files changed

+17578
-4395
lines changed

Some content is hidden

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

258 files changed

+17578
-4395
lines changed

‎README.md

Lines changed: 72 additions & 122 deletions
Large diffs are not rendered by default.

‎pics/.DS_Store

-6 KB
Binary file not shown.

‎problems/0001.两数之和.md

Lines changed: 114 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
## 1. 两数之和
99

10-
[力扣题目链接](https://leetcode-cn.com/problems/two-sum/)
10+
[力扣题目链接](https://leetcode.cn/problems/two-sum/)
1111

1212
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
1313

@@ -24,15 +24,26 @@
2424

2525
## 思路
2626

27-
很明显暴力的解法是两层for循环查找,时间复杂度是$O(n^2)$。
27+
建议看一下我录的这期视频:[梦开始的地方,Leetcode:1.两数之和](https://www.bilibili.com/video/BV1aT41177mK),结合本题解来学习,事半功倍。
28+
29+
很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
2830

2931
建议大家做这道题目之前,先做一下这两道
3032
* [242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html)
3133
* [349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html)
3234

3335
[242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html)这道题目是通过set作为哈希表来解决哈希问题。
3436

35-
本题呢,则要使用map,那么来看一下使用数组和set来做哈希法的局限。
37+
38+
首先我在强调一下 **什么时候使用哈希法**,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
39+
40+
本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。
41+
42+
那么我们就应该想到使用哈希法了。
43+
44+
因为本地,我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**
45+
46+
再来看一下使用数组和set来做哈希法的局限。
3647

3748
* 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
3849
* set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。
@@ -43,20 +54,38 @@ C++中map,有三种类型:
4354

4455
|映射 |底层实现 | 是否有序 |数值是否可以重复 | 能否更改数值|查询效率 |增删效率|
4556
|---|---| --- |---| --- | --- | ---|
46-
|std::map |红黑树 |key有序 |key不可重复 |key不可修改 | $O(\log n)$|$O(\log n)$ |
47-
|std::multimap | 红黑树|key有序 | key可重复 | key不可修改|$O(\log n)$ |$O(\log n)$ |
48-
|std::unordered_map |哈希表 | key无序 |key不可重复 |key不可修改 |$O(1)$ | $O(1)$|
57+
|std::map |红黑树 |key有序 |key不可重复 |key不可修改 | O(log n)|O(log n) |
58+
|std::multimap | 红黑树|key有序 | key可重复 | key不可修改|O(log n)|O(log n) |
59+
|std::unordered_map |哈希表 | key无序 |key不可重复 |key不可修改 |O(1) | O(1)|
4960

5061
std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。
5162

5263
同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://www.programmercarl.com/哈希表理论基础.html)
5364

54-
**这道题目中并不需要key有序,选择std::unordered_map 效率更高!**
65+
**这道题目中并不需要key有序,选择std::unordered_map 效率更高!** 使用其他语言的录友注意了解一下自己所用语言的数据结构就行。
66+
67+
接下来需要明确两点:
68+
69+
* **map用来做什么**
70+
* **map中key和value分别表示什么**
71+
72+
map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target)
5573

56-
解题思路动画如下:
74+
接下来是map中key和value分别表示什么。
5775

58-
![](https://code-thinking.cdn.bcebos.com/gifs/1.两数之和.gif)
76+
这道题 我们需要 给出一个元素,判断这个元素是否出现过,如果出现过,返回这个元素的下标。
5977

78+
那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。
79+
80+
所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下表}。
81+
82+
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素比配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。
83+
84+
过程如下:
85+
86+
![过程一](https://code-thinking-1253855093.file.myqcloud.com/pics/20220711202638.png)
87+
88+
![过程二](https://code-thinking-1253855093.file.myqcloud.com/pics/20220711202708.png)
6089

6190
C++代码:
6291

@@ -66,18 +95,31 @@ public:
6695
vector<int> twoSum(vector<int>& nums, int target) {
6796
std::unordered_map <int,int> map;
6897
for(int i = 0; i < nums.size(); i++) {
69-
auto iter = map.find(target - nums[i]);
98+
// 遍历当前元素,并在map中寻找是否有匹配的key
99+
auto iter = map.find(target - nums[i]);
70100
if(iter != map.end()) {
71101
return {iter->second, i};
72102
}
73-
map.insert(pair<int, int>(nums[i], i));
103+
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
104+
map.insert(pair<int, int>(nums[i], i));
74105
}
75106
return {};
76107
}
77108
};
78109
```
79110
111+
## 总结
112+
113+
本题其实有四个重点:
114+
115+
* 为什么会想到用哈希表
116+
* 哈希表为什么用map
117+
* 本题map是用来存什么的
118+
* map中的key和value用来存什么的
119+
120+
把这四点想清楚了,本题才算是理解透彻了。
80121
122+
很多录友把这道题目 通过了,但都没想清楚map是用来做什么的,以至于对代码的理解其实是 一知半解的。
81123
82124
83125
## 其他语言版本
@@ -221,13 +263,15 @@ php
221263
```php
222264
function twoSum(array $nums, int $target): array
223265
{
224-
for ($i = 0; $i < count($nums);$i++) {
225-
// 计算剩下的数
226-
$residue = $target - $nums[$i];
227-
// 匹配的index,有则返回index, 无则返回false
228-
$match_index = array_search($residue, $nums);
229-
if ($match_index !== false && $match_index != $i) {
230-
return array($i, $match_index);
266+
$map = [];
267+
foreach($nums as $i => $num) {
268+
if (isset($map[$target - $num])) {
269+
return [
270+
$i,
271+
$map[$target - $num]
272+
];
273+
} else {
274+
$map[$num] = $i;
231275
}
232276
}
233277
return [];
@@ -250,28 +294,61 @@ func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
250294
}
251295
```
252296

253-
PHP:
254-
```php
255-
class Solution {
256-
/**
257-
* @param Integer[] $nums
258-
* @param Integer $target
259-
* @return Integer[]
260-
*/
261-
function twoSum($nums, $target) {
262-
if (count($nums) == 0) {
263-
return [];
264-
}
265-
$table = [];
266-
for ($i = 0; $i < count($nums); $i++) {
267-
$temp = $target - $nums[$i];
268-
if (isset($table[$temp])) {
269-
return [$table[$temp], $i];
297+
298+
Scala:
299+
```scala
300+
object Solution {
301+
// 导入包
302+
import scala.collection.mutable
303+
def twoSum(nums: Array[Int], target: Int): Array[Int] = {
304+
// key存储值,value存储下标
305+
val map = new mutable.HashMap[Int, Int]()
306+
for (i <- nums.indices) {
307+
val tmp = target - nums(i) // 计算差值
308+
// 如果这个差值存在于map,则说明找到了结果
309+
if (map.contains(tmp)) {
310+
return Array(map.get(tmp).get, i)
311+
}
312+
// 如果不包含把当前值与其下标放到map
313+
map.put(nums(i), i)
314+
}
315+
// 如果没有找到直接返回一个空的数组,return关键字可以省略
316+
new Array[Int](2)
317+
}
318+
}
319+
```
320+
321+
C#:
322+
```csharp
323+
public class Solution {
324+
public int[] TwoSum(int[] nums, int target) {
325+
Dictionary<int ,int> dic= new Dictionary<int,int>();
326+
for(int i=0;i<nums.Length;i++){
327+
int imp= target-nums[i];
328+
if(dic.ContainsKey(imp)&&dic[imp]!=i){
329+
return new int[]{i, dic[imp]};
270330
}
271-
$table[$nums[$i]] = $i;
331+
if(!dic.ContainsKey(nums[i])){
332+
dic.Add(nums[i],i);
333+
}
334+
}
335+
return new int[]{0, 0};
336+
}
337+
}
338+
```
339+
340+
Dart:
341+
```dart
342+
List<int> twoSum(List<int> nums, int target) {
343+
var tmp = [];
344+
for (var i = 0; i < nums.length; i++) {
345+
var rest = target - nums[i];
346+
if(tmp.contains(rest)){
347+
return [tmp.indexOf(rest), i];
272348
}
273-
return [];
349+
tmp.add(nums[i]);
274350
}
351+
return [0 , 0];
275352
}
276353
```
277354

‎problems/0005.最长回文子串.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# 5.最长回文子串
1010

11-
[力扣题目链接](https://leetcode-cn.com/problems/longest-palindromic-substring/)
11+
[力扣题目链接](https://leetcode.cn/problems/longest-palindromic-substring/)
1212

1313
给你一个字符串 s,找到 s 中最长的回文子串。
1414

0 commit comments

Comments
(0)

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