目录
一、242. 有效的字母异位词
题目链接:力扣
文章讲解:代码随想录
视频讲解: 学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词
题目:
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
代码:
class Solution {
public:
bool isAnagram(string s, string t) {
int hash[26] = {0};
for(auto i : s)
hash[i - 'a']++;
for(auto i : t)
hash[i - 'a']--;
for(int i = 0; i < 26; i++)
if (hash[i] != 0) return false;
return true;
}// 2:04
};
时间复杂度: O(n) 空间复杂度: O(1)
⏲:2:04
总结:涉及只包含字母的个数统计(或能用ASCII码的统计)用数组哈希。
二、349. 两个数组的交集
题目链接:力扣
文章讲解:代码随想录
视频讲解:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集
题目:给定两个数组 nums1和 nums2,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
代码:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> ans;
unordered_set<int> set(nums1.begin(), nums1.end());
for (int num : nums2)
if (set.find(num) != set.end())
ans.insert(num);
return vector<int>(ans.begin(), ans.end());
}//5:32
};
时间复杂度: O(n) 空间复杂度: O(n)
⏲:5:32
总结:哈希值比较少、分散、跨度非常大(即没有限制范围)用set。
附set的分类:
集合 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::set | 红黑树 | 有序 | 否 | 否 | O(log n) | O(log n) |
std::multiset | 红黑树 | 有序 | 是 | 否 | O(logn) | O(logn) |
std::unordered_set | 哈希表 | 无序 | 否 | 否 | O(1) | O(1) |
三、202. 快乐数
题目链接:力扣
文章讲解:代码随想录
视频讲解:
题目:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
代码:
class Solution {
public:
bool isHappy(int n) {
unordered_set<int> hash;
while(n != 1){
int x = 0;
while(n){
x += (n%10) * (n%10);
n /= 10;
}
n = x;
if (hash.find(x) != hash.end()) return false;
else hash.insert(x);
}
return true;//6:09
}
};
时间复杂度: O(log(n)) 空间复杂度: O(log(n))
⏲:6:09
总结:因为循环可判断此题关键在重复元素的出现,进而使用哈希。
四、1. 两数之和
题目链接:力扣
文章讲解:代码随想录
题目:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hash;
for(int i = 0; i < nums.size(); i++){
int find = target - nums[i];
if(hash.find(find) != hash.end()) return {i, hash[find]};
else hash.insert(pair<int, int>(nums[i], i));
}
return {};
}//5:47
};
时间复杂度: O(n) 空间复杂度: O(n)
⏲:5:47
总结:当哈希时,发现同时需要记录两个(及以上)值就用map。
附map的分类:
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::map | 红黑树 | key有序 | key不可重复 | key不可修改 | O(log n) | O(log n) |
std::multimap | 红黑树 | key有序 | key可重复 | key不可修改 | O(log n) | O(log n) |
std::unordered_map | 哈希表 | key无序 | key不可重复 | key不可修改 | O(1) | O(1) |