代码随心录第六天|哈希表——Leecode 242.有效的字母异位词、 349. 两个数组的交集 、 202. 快乐数 、1. 两数之和
Leecode 242.有效的字母异位词
题目链接:https://leetcode.cn/problems/valid-anagram/description/
题目描述:
思路:暴力解法---两层for循环;哈希表--数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。
解答:
假设我们有这样一个字符串 s = "aab" ,来看一下代码 record[s[i] - 'a']++; 是怎么运行的:
当 i = 0 时:
- s[0] 的值是 'a' 。
- s[0] - 'a' ,因为 'a' 的 ASCII 码值是 97, 97 - 97 = 0 。
- 那么 record[s[0] - 'a']++ 就相当于 record[0]++ , record 数组初始值都是 0,执行这一步后 record[0] 的值变为 1,这表示字符 'a' 出现了 1 次。
当 i = 1 时:
- s[1] 的值还是 'a' 。
- s[1] - 'a' 同样是 97 - 97 = 0 。
- 所以 record[s[1] - 'a']++ 也就是 record[0]++ , record[0] 的值从 1 变为 2,说明字符 'a' 又出现了一次,现在一共出现了 2 次。
当 i = 2 时:
- s[2] 的值是 'b' 。
- 'b' 的 ASCII 码值是 98,所以 s[2] - 'a' = 98 - 97 = 1 。
- 那么 record[s[2] - 'a']++ 就是 record[1]++ , record[1] 的值从 0 变为 1,这意味着字符 'b' 出现了 1 次。
再看另一个字符串 s = "abb" :
当 i = 0 时:
- s[0] 是 'a' , s[0] - 'a' = 0 , record[0]++ 后 record[0] 变为 1。
当 i = 1 时:
- s[1] 是 'b' , s[1] - 'a' = 1 , record[1]++ 后 record[1] 变为 1。
当 i = 2 时:
- s[2] 是 'b' , s[2] - 'a' = 1 , record[1]++ 后 record[1] 变为 2。
record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。
最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
Leecode 349. 两个数组的交集
题目链接:https://leetcode.cn/problems/intersection-of-two-arrays/description/
题目描述:
思路:这道题目没有限制数值的大小,就无法使用数组来做哈希表。如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。此时就要使用另一种结构体了,set ,关于set,C++ 给提供了如下三种可用的数据结构,std::set,std::multise,std::unordered_set,std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
解答:
Leecode 202. 快乐数
题目链接:https://leetcode.cn/problems/happy-number/description/
题目描述:
思路:
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
判断sum是否重复出现就可以使用unordered_set。
解答:
Leecode 1. 两数之和
题目描述:
思路:当查询一个数字是否出现过,或在集合中,优先想到使用哈希表。需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map。
解答: