关于我们什么时候使用哈希法?当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
242. 有效的字母异位词
本题还是非常简单的,设置一个int型的数组大小为 26,然后分别遍历两个字符串即可;
具体代码如下
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for (int i = 0; i < s.size(); i++) {
// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
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) {
// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return false;
}
}
// record数组所有元素都为零0,说明字符串s和t是字母异位词
return true;
}
};
349. 两个数组的交集
拿到这题题目,首先关注到题目给我们的提示,不考虑输出结果的顺序,那么我们可以想到“无序”这一关键词,从而联想到使用unordered_set来解答这题题目,具体思路:
先创建一个unordered_set,并且将数组1存放进去,然后去遍历数组2,看数组2中的数是否能在数组1中找到,能找到的话就添加进result中
具体代码如下:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int>result;
unordered_set<int> s(nums1.begin(),nums1.end());
for(int n:nums2){
if(s.find(n)!=s.end()){
result.insert(n);
}
}
return vector<int>(result.begin(),result.end());
}
};
202. 快乐数
本题看似是一题数学题,其实不是,重点关注题目说了会无限循环,那么就是说,在求和的时候,sum会重复出现,所以我们只要拿一个unodered_set来存放已经出现过得数即可,如果发现数重复了,证明已经进入了死循环。
具体代码如下:
class Solution {
public:
int func(int n){
int result=0;
while(n>0){
result+=(n%10)*(n%10);
n/=10;
}
return result;
}
bool isHappy(int n) {
unordered_set<int> myset;
while(1){
int sum=func(n);
if(sum==1){
return true;
}
if(myset.find(sum)!=myset.end()){
return false;
}else{
myset.insert(sum);
}
n=sum;
}
}
};
1. 两数之和
本题虽然是力扣的第一题,但是其实也没有这么简单。
那么我们又回到文章开头那句话,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
我们这题其实就是一个查找元素是否出现过的题目!
具体思路如下,我们先设置一个unodered_map,然后遍历数组,直接在map中寻找是否有target-nums[i]的值,找到后直接返回它和i即可,没有找到的话,我们就存放这组数据在我们定义的map中。
具体代码如下:
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++){
// 遍历当前元素,并在map中寻找是否有匹配的key
auto iter=map.find(target-nums[i]);
if(iter!=map.end()){
return {iter->second,i};
}
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
map.insert(pair<int,int>(nums[i],i));
}
return { };
}
};