9
9
10
10
> 哈希表总结篇如约而至
11
11
12
- 哈希表系列也是早期讲解的时候没有写总结篇,所以选个周末给补上,毕竟「代码随想录」的系列怎么能没有总结篇呢[ 机智] 。
13
12
14
13
# 哈希表理论基础
15
14
16
- 在[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA ) 中,我们介绍了哈希表的基础理论知识,不同于枯燥的讲解,这里介绍了都是对刷题有帮助的理论知识点。
15
+ 在[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg ) 中,我们介绍了哈希表的基础理论知识,不同于枯燥的讲解,这里介绍了都是对刷题有帮助的理论知识点。
17
16
18
17
** 一般来说哈希表都是用来快速判断一个元素是否出现集合里** 。
19
18
29
28
* set(集合)
30
29
* map(映射)
31
30
32
- 在C++语言中,set 和 map 都分别提供了三种数据结构,每种数据结构的底层实现和用途都有所不同,在[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA ) 中我给出了详细分析,这一知识点很重要!
31
+ 在C++语言中,set 和 map 都分别提供了三种数据结构,每种数据结构的底层实现和用途都有所不同,在[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg ) 中我给出了详细分析,这一知识点很重要!
33
32
34
33
例如什么时候用std::set,什么时候用std::multiset,什么时候用std::unordered_set,都是很有考究的。
35
34
41
40
42
41
一些应用场景就是为数组量身定做的。
43
42
44
- 在[ 哈希表: 有效的字母异位词] ( https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig ) 中,我们提到了数组就是简单的哈希表,但是数组的大小是受限的!
43
+ 在[ 242. 有效的字母异位词] ( https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA ) 中,我们提到了数组就是简单的哈希表,但是数组的大小是受限的!
45
44
46
45
这道题目包含小写字母,那么使用数组来做哈希最合适不过。
47
46
48
- 在[ 哈希表: 赎金信] ( https://mp.weixin.qq.com/s/sYZIR4dFBrw_lr3eJJnteQ ) 中同样要求只有小写字母,那么就给我们浓浓的暗示,用数组!
47
+ 在[ 383. 赎金信] ( https://mp.weixin.qq.com/s/qAXqv--UERmiJNNpuphOUQ ) 中同样要求只有小写字母,那么就给我们浓浓的暗示,用数组!
49
48
50
- 本题和[ 哈希表: 有效的字母异位词] ( https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig ) 很像,[ 哈希表: 有效的字母异位词] ( https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig ) 是求 字符串a 和 字符串b 是否可以相互组成,在[ 哈希表: 赎金信] ( https://mp.weixin.qq.com/s/sYZIR4dFBrw_lr3eJJnteQ ) 中是求字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
49
+ 本题和[ 242. 有效的字母异位词] ( https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA ) 很像,[ 242. 有效的字母异位词] ( https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA ) 是求 字符串a 和 字符串b 是否可以相互组成,在[ 383. 赎金信] ( https://mp.weixin.qq.com/s/qAXqv--UERmiJNNpuphOUQ ) 中是求字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
51
50
52
51
一些同学可能想,用数组干啥,都用map不就完事了。
53
52
56
55
57
56
## set作为哈希表
58
57
59
- 在[ 哈希表: 两个数组的交集] ( https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA ) 中我们给出了什么时候用数组就不行了,需要用set。
58
+ 在[ 349. 两个数组的交集] ( https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q ) 中我们给出了什么时候用数组就不行了,需要用set。
60
59
61
60
这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
62
61
67
66
68
67
所以此时一样的做映射的话,就可以使用set了。
69
68
70
- 关于set,C++ 给提供了如下三种可用的数据结构:(详情请看[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA ) )
69
+ 关于set,C++ 给提供了如下三种可用的数据结构:(详情请看[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg ) )
71
70
72
71
* std::set
73
72
* std::multiset
74
73
* std::unordered_set
75
74
76
75
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希, 使用unordered_set 读写效率是最高的,本题并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
77
76
78
- 在[ 哈希表: 快乐数] ( https://mp.weixin.qq.com/s/G4Q2Zfpfe706gLK7HpZHpA ) 中,我们再次使用了unordered_set来判断一个数是否重复出现过。
77
+ 在[ 202. 快乐数] ( https://mp.weixin.qq.com/s/n5q0ujxxrjQS3xuh3dgqBQ ) 中,我们再次使用了unordered_set来判断一个数是否重复出现过。
79
78
80
79
81
80
## map作为哈希表
82
81
83
- 在[ 哈希表: 两数之和] ( https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ ) 中map正式登场。
82
+ 在[ 1. 两数之和] ( https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ ) 中map正式登场。
84
83
85
84
来说一说:使用数组和set来做哈希法的局限。
86
85
@@ -89,29 +88,29 @@ std::set和std::multiset底层实现都是红黑树,std::unordered_set的底
89
88
90
89
map是一种` <key, value> ` 的结构,本题可以用key保存数值,用value在保存数值所在的下表。所以使用map最为合适。
91
90
92
- C++提供如下三种map::(详情请看[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA ) )
91
+ C++提供如下三种map::(详情请看[ 关于哈希表,你该了解这些!] ( https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg ) )
93
92
94
93
* std::map
95
94
* std::multimap
96
95
* std::unordered_map
97
96
98
97
std::unordered_map 底层实现为哈希,std::map 和std::multimap 的底层实现是红黑树。
99
98
100
- 同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解),[ 哈希表: 两数之和] ( https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ ) 中并不需要key有序,选择std::unordered_map 效率更高!
99
+ 同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解),[ 1. 两数之和] ( https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ ) 中并不需要key有序,选择std::unordered_map 效率更高!
101
100
102
- 在[ 哈希表:四数相加II ] ( https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA ) 中我们提到了其实需要哈希的地方都能找到map的身影。
101
+ 在[ 454.四数相加 ] ( https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw ) 中我们提到了其实需要哈希的地方都能找到map的身影。
103
102
104
- 本题咋眼一看好像和[ 18. 四数之 ] ( https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A ) ,[ 15.三数之和] ( https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g ) 差不多,其实差很多!
103
+ 本题咋眼一看好像和[ 18. 四数之和 ] ( https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q ) ,[ 15.三数之和] ( https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg ) 差不多,其实差很多!
105
104
106
- ** 关键差别是本题为四个独立的数组,只要找到A[ i] + B[ j] + C[ k] + D[ l] = 0就可以,不用考虑重复问题,而[ 18. 四数之和] ( https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g ) ,[ 15.三数之和] ( https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A ) 是一个数组(集合)里找到和为0的组合,可就难很多了!**
105
+ ** 关键差别是本题为四个独立的数组,只要找到A[ i] + B[ j] + C[ k] + D[ l] = 0就可以,不用考虑重复问题,而[ 18. 四数之和] ( https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q ) ,[ 15.三数之和] ( https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg ) 是一个数组(集合)里找到和为0的组合,可就难很多了!**
107
106
108
107
用哈希法解决了两数之和,很多同学会感觉用哈希法也可以解决三数之和,四数之和。
109
108
110
109
其实是可以解决,但是非常麻烦,需要去重导致代码效率很低。
111
110
112
- 在[ 哈希表:解决了两数之和,那么能解决三数之和么? ] ( https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A ) 中我给出了哈希法和双指针两个解法,大家就可以体会到,使用哈希法还是比较麻烦的。
111
+ 在[ 15.三数之和 ] ( https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg ) 中我给出了哈希法和双指针两个解法,大家就可以体会到,使用哈希法还是比较麻烦的。
113
112
114
- 所以 [ 18. 四数之 ] ( https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A ) , [ 15.三数之和 ] ( https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g ) 都推荐使用双指针法 !
113
+ 所以18. 四数之和, 15.三数之和都推荐使用双指针法 !
115
114
116
115
# 总结
117
116
@@ -127,19 +126,6 @@ std::unordered_map 底层实现为哈希,std::map 和std::multimap 的底层
127
126
128
127
129
128
130
- ## 其他语言版本
131
-
132
-
133
- Java:
134
-
135
-
136
- Python:
137
-
138
-
139
- Go:
140
-
141
-
142
-
143
129
144
130
-----------------------
145
131
* 作者微信:[ 程序员Carl] ( https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw )
0 commit comments