一、理论基础
1.1 哈希表
哈希表(Hash table),关键码是数组的索引下标,通过下标直接访问数组中的元素,如下图所示:
一般哈希表用来快速判断一个元素是否出现在一个集合里。
哈希函数,是指将相关元素直接映射到哈希表上的索引,通过HashCode把名字转化为数值。
1.2 哈希碰撞
哈希碰撞是指两元素映射到索引下标相同的位置,这一现象叫做哈希碰撞。
二、题目
2.1 —242.有效的字母异位词
本质就是判断两个字符串是不是由相同的字母组成,但是位置可以变化,例如:abbc和bacb,但是abbc和bacd不是。
思路:数组就是一个简单的哈希表,而这道题目中的字符串只有小写字母,定义一个数组,来记录字符串s里的字符出现次数。定义一个数组叫做hash,大小为26,初始化为0,因为字符a到字符z的ascii也是26个连续数值。
需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII是连续的26个字母,将字符a映射到下标0,相应的字符串z映射到下标25。遍历字符串s的时候,只需要将s[i]-'a'所在元素做+1,无需严格记住所在字符的ascll,给出一个数值就行。
只要求出一个相对值就行了,这样将字符串s中字符出现的次数就可以统计出来了。
class Solution {
public:
bool isAnagram(string s, string t) {
int hash[26]={0};
for (int i=0;i<s.size();i++)
{
hash[s[i]-'a']++;
}
for (int i =0;i<t.size();i++)
{
hash[t[i]-'a']--;
}
for (int i =0;i<26;i++)
{
if(hash[i] !=0)
{
return false;
}
}
return true;
}
};
2.2—349 两个数组的交集
该题需注意,输出结果唯一,即输出结果需要去重,同时可以不考虑输出结果的顺序。本题无法使用数组来做hash,因为题目没有限制数值的大小。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int>result_set;
unordered_set<int>nums_set(nums1.begin(),nums1.end());
for (int num:nums2)
{
if (nums_set.find(num)!=nums_set.end())
{
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};