day6第三章 哈希表part01
1.哈希表理论基础
什么时候用
快速判断一个元素是否出现集合里
2.有效的字母异位词
题目:https://leetcode.cn/problems/valid-anagram/
题解:
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26]={0};//字母表只有26个字母,有限制范围考虑用数组
//要初始化哈希表里元素都为0
for(int i=0;i<s.size();i++){
record[s[i]-'a']++;/*'a'把a转换为ascii码;a是基准;若s[i]为a,
record[0]++; 若s[i]=b,record[1]++*/
}
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;
}
};
盲点:
1.表示数组长度: 数组s[10], 长度s.size()
debug
1.没初始化哈希表数组元素值
int record[26];
改正:
int record[26]={0};
3.两个数组的交集
题目:https://leetcode.cn/problems/intersection-of-two-arrays/
题解:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result;//unordered_set起去重的作用,相同元素只存一个
int hash[1005]={0};
for(int i=0;i<nums1.size();i++){
hash[nums1[i]]=1;
}
for(int i=0;i<nums2.size();i++){
if(hash[nums2[i]]==1){//中括号位置要看准
result.insert(nums2[i]);//将满足条件的nums2[i]输入到哈希表
}
}
return vector <int>(result.begin(),result.end());//set转换为vector的方式
}
};
debug:
1.set转换为vector,result是set类型;
return vector <int>(result.begin(),result.end());
4.快乐数
题目:https://leetcode.cn/problems/happy-number/
题解:
class Solution {
public:
int getSum(int n){
int sum=0;
while(n){//n为0时,说明已除完最后一位(变成小数)
sum+=(n%10)*(n%10);//每一位单数的平方和叠加
n/=10;//找下一位
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> gather;
while(1){//加while(1)的作用?
int sum=getSum(n);
if(sum==1){
return true;
}
if(gather.find(sum)!=gather.end()){//如果在set中找到了sum,说明个位数
//平方和有重复,即无限循环始终变不到1;并非快乐数
return false;
}
else{
gather.insert(sum);
}
n=sum;//平方总和不为1,但也没有重复(无限循环),继续算各位单数平方数
}
}
};
盲点:
1.
if (set.find(sum) != set.end())
//如果在set中找到了sum,说明个位数平方和有重复,即无限循环始终变不到1;并非快乐数
2.
if(gather.find(sum)!=gather.end()){//如果在set中找到了sum
3.加while(1)的作用?
5.两数之和
题目:https://leetcode.cn/problems/two-sum/
题解:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int>map; //map{元素数值,元素下标}
for(int i=0;i<nums.size();i++){
int goal=target-nums[i];//当前数为nums[i],找相加为target值的另一个数
if(map.find(goal)!=map.end()){//如果在map里找到该数(说明已遍历过)
return {map.find(goal)->second, i};// map.find(goal)->second 表示的是这个元素的value的值,即元素所在下标;以及当前数下标
}
//else{ 前面return已让句子结束
map.insert(pair<int,int>(nums[i],i));//先输入遍历过的数
//}
}
return {};//没找到返回空
}
};
图示:
图一https://code-thinking-1253855093.file.myqcloud.com/pics/20220711202638.png
图二https://code-thinking-1253855093.file.myqcloud.com/pics/20230220223536.png
盲点:
1.为什么使用map
使用 map{key,value}结构来存放,key来存元素数值,value来存元素所在下标
本题要判断元素有没有被遍历过,还要记录其下标位置;有两个东西要保存,用map
2.为什么用unordered_map
底层实现为哈希表,查找效率更高
3.map用来干什么
存放遍历过的元素
if(map.find(goal)!=map.end()){//如果在map里找到goal
b->first会得到b中key的值,即元素数值
b->second会得到b中value的值, 即元素所在下标
map.find(goal)->first //map中goal元素的值
map.find(goal)->second //map中goal元素所在下标
debug
map.insert(pair<int,int>(nums[i],i));
pair<int,int>?