代码随想录算法训练营第六天 | 哈希表理论基础、Leetcode242.有效的字母异位词 、Leetcode349. 两个数组的交集、Leetcode202. 快乐数、Leetcode1. 两数之和
哈希表理论基础
文章链接:哈希表理论基础
哈希法解决的主要问题:快速判断一个元素是否在集合里
哈希法包含的结构:数组、set、multiset、unordered_set、map、multimap、unordered_map
其中最常用的就是数组、unordered_set、unordered_map
unordered_set底层实现为哈希表,set 和multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。
unordered_map 底层实现为哈希表,map 和multimap 的底层实现是红黑树。同理,map 和multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。
注意:
- 遗忘了的数组初始化方法:
int a[n]={0}
- 遗忘了unordered_set、unordered_map初始化方法,后续要专门总结一下STL容器的使用
Leetcode242.有效的字母异位词
就很简单粗暴。。。用个数组直接存对应字母出现次数,没啥可说的
class Solution {
public:
bool isAnagram(string s, string t) {
int count[26]={0};
for(int i=0;i<s.size();i++){
count[s[i]-'a']++;
}
for(int i=0;i<t.size();i++){
count[t[i]-'a']--;
}
for(int i=0;i<26;i++){
if(count[i]!=0) return false;
}
return true;
}
};
Leetcode349. 两个数组的交集
unordered_set用的不熟练,后面总结一下。
注意:
- 初始化时
unordered_set<int> a(b.begin(),b.end());
可以实现从vector到unordered_set的拷贝,反过来也同理,可以把unordered_set里面元素拷贝到vector中。 - 本质上跟vector差不多,就是不重复,还有find()函数比较好用
下面是用set存储
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;
unordered_set<int> record(nums1.begin(),nums1.end());//拷贝nums1里面的元素
for(int i=0;i<nums2.size();i++){
if(record.find(nums2[i])!=record.end()) result.insert(nums2[i]);
}
return vector<int>(result.begin(),result.end());
}
};
用数组存储可以比set省一点内存空间
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;
int record[1000]={0};
for(int i=0;i<nums1.size();i++){
record[nums1[i]]=1;
}
for(int i=0;i<nums2.size();i++){
if(record[nums2[i]]) result.insert(nums2[i]);
}
return vector<int>(result.begin(),result.end());
}
};
Leetcode202. 快乐数
判断某个值在不在,并且要无重复的时候,首先考虑使用unordered_set。
这道题就是利用它来判断有没有进入无限循环。
class Solution {
public:
int getsum(int n){//计算平方和
int sum=0;
while(n/10 != 0){
sum += (n%10)*(n%10);
n=n/10;
}
sum+=n*n;
return sum;
}
bool isHappy(int n) {
unordered_set<int> sums;
int sum=getsum(n);
while(sums.find(sum)==sums.end()){//判断在不在
if(sum==1) return true;//在就返回true
sums.insert(sum);
sum=getsum(sum);
}
return false;
}
};
Leetcode1. 两数之和
回忆起来unordered_map的用法:最主要的是里面塞的是对组pair<typea,typeb>(a.b)
总的来说没啥好说的,都是基础用法。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map;
for(int i=0;i<nums.size();i++){
if(map.find(target-nums[i])!=map.end()) return {map[target-nums[i]],i};
map.insert(pair<int,int>(nums[i],i));
}
return {};
}
};