代码随想录 | Day07 | 哈希表:有效的字母异位词&&两个数组的交集&&快乐数
主要学习内容:
1.哈希表的使用
2.set的相关操作,find和count函数
242.有效的字母异位词
242. 有效的字母异位词 - 力扣(LeetCode)
解法:哈希表
思路:map容器一个记录字符一个记录数量不一样直接输出false即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public: bool isAnagram(string s, string t) { if(s.size()!=t.size()) return false; unordered_map<char,int> ps; unordered_map<char,int> pt; for(auto c:s) ps[c]++; for(auto c:t) pt[c]++; int n=s.size(); for(auto c:s) if(ps[c]!=pt[c]) return false; return true; }
};
|
349.两个数组的交集
349. 两个数组的交集 - 力扣(LeetCode)
解法:哈希表
思路:
1.如果使用undered_map记录数字有没有出现过然后一一判断的话,会出现结果集合中重复元素的出现
比如nums1是1,2,2,1而nums2是2,2
res就会是2,2而不是2
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { vector<int> res; unordered_map<int,int> p; for(auto c:nums1) p[c]++; for(auto c:nums2) if(p[c]!=0) res.push_back(c); return res; } };
|
2.自认为改进了其实还是错的
把nums1和nums2对调一下就还是错的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { vector<int> res; unordered_map<int,int> p; for(auto c:nums1) p[c]++; for(auto c:nums2) if(p[c]==1) res.push_back(c); else if(p[c]>1) { p[c]=0; res.push_back(c); } return res; } };
|
3.正确写法是用set,set不允许重复,然后返回结果是直接用set初始化vector然后返回即可
1 2 3 4 5 6 7 8 9 10 11
| class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { unordered_set<int> r; unordered_set<int> s(nums1.begin(),nums1.end()); for(int num:nums2) if(s.find(num)!=s.end()) r.insert(num); return vector<int>(r.begin(),r.end()); } };
|
202.快乐数
202. 快乐数 - 力扣(LeetCode)
解法:哈希表
关键:要想到陷入了无限循环是有了重复的数字出现才导致了无限循环,第一次做没有想明白这一点
知道了这一点剩下的就很容易了
把所有得到的数字都加入到set中,有重复就说明无限循环然后直接false,没有重复最后肯定到1,等于1就返回true即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public: int getnum(int n) { int res=0; while(n) { res+=((n%10)*(n%10)); n/=10; } return res; } bool isHappy(int n) { unordered_set<int> s; while(true) { int temp=getnum(n); if(temp==1) return true; if(s.count(temp)) return false; s.insert(temp); n=temp; } return false; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { std::unordered_map <int,int> 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<int, int>(nums[i], i)); } return {}; } };
|
1.两数之和
梦开始的地方
1. 两数之和 - 力扣(LeetCode)
解法:哈希表
思路
用unordered_map来进行元素标记,first为nums[i],second为对应元素下标i,然后再哈希表中查找target-i,能找到说明就是答案,找不到就说明没有答案
错误写法:
先建立了一张哈希表,然后再遍历一遍去匹配有没有答案,问题是如果碰到重复元素,map中只会记录一个,自然而然下标也只有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> s; int l,r; for(int i=0;i<nums.size();i++) s[nums[i]]=i; for(auto c:nums) if(s.find(target-c)!=s.end()) { l=s[c]; r=s[target-c]; } return {l,r}; } };
|
正确写法:
在第一遍遍历时候就开始找,这样做,重复元素的nums[i]和i就不会进入哈希表而是直接输出成为答案,从而避免了这样的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> s; for(int i=0;i<nums.size();i++) { auto it=s.find(target-nums[i]); if(it!=s.end()) return {it->second,i}; else s.insert({nums[i],i}); } return { }; } };
|