在写这些题之前,我们应该知道一些哈希表的理论基础(哈希表、哈希函数、哈希碰撞,拉链法、线性探测法、常见的三种哈希结构)。
什么时候想到用哈希法:当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑 哈希法。
LeetCode 242.有效的字母异位词
题目链接:242. 有效的字母异位词 - 力扣(LeetCode)
视频链接:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili
思路
首先,需要定义一个大小为26的数组,因为a--z字母、ASCII是连续的26个,把它初始化为零。然后定义一个数组分别记录字符串s、t中的字符出现的次数,找s时++,找t时--。最后如果定义的这个数组所有元素都为零0,说明字符串s和t是字母异位词。过程如下图所示:
代码实现:
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for(int i = 0;i < s.size();i++) {
record[s[i] - 'a']++;
}
for(int i = 0;i < t.size();i++) {
record[t[i] - 'a']--;
}
for(int i = 0;i < 26;i++) {
if(record[i] != 0) {
return false;
}
}
return true;
}
};
·时间复杂度:O(n)
·空间复杂度:O(1)
LeetCode 349. 两个数组的交集
题目链接:349. 两个数组的交集 - 力扣(LeetCode)
视频链接:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili
思路
注意题目特意说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序
注意:使用数组来做哈希的题目,是因为题目都限制了数值的大小。
代码实现:
class Solution {
public:
vector intersection(vector& nums1, vector& nums2) {
unordered_set result_set;
int hash[1001] = {0};
for(int num : nums1) {
hash[num] = 1;
}
for (int num : nums2) {
if (hash[num] == 1) {
result_set.insert(num);
}
}
return vector(result_set.begin(), result_set.end());
}
};
·时间复杂度:O(m + n)
·空间复杂度: O(n)
LeetCode 202. 快乐数
题目链接:202. 快乐数 - 力扣(LeetCode)
思路
题目中说了会无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
还有一个难点就是求和的过程,需要对取数值各个位上的单数操作熟悉。
代码实现:
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set set;
while(1) {
int sum = getSum(n);
if (sum == 1) {
return true;
}
if (set.find(sum) != set.end()) {
return false;
} else {
set.insert(sum);
}
n = sum;
}
}
};
·时间复杂度:O(logn)
·空间复杂度:O(logn)
LeetCode 1. 两数之和
题目链接:1. 两数之和 - 力扣(LeetCode)
视频链接:梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!_哔哩哔哩_bilibili
思路
写这道题需要思考清楚map是用来做什么的,key、value是用来存什么的。map是用来存放我们遍历过的元素,key是用来存元素的,而value则是用来存下标的。如图所示:
代码实现:
class Solution {
public:
vector twoSum(vector& nums, int target) {
std::unordered_map map;
for(int i = 0; i < nums.size(); i++) {
auto iter = map.find(target - nums[i]);
if(iter != map.end()) {
return {iter->second, i};
}
map.insert(pair(nums[i], i));
}
return {};
}
};
·时间复杂度:O(n)
·空间复杂度:O(n)