对于这类型需要记录下已经遍历过的元素,并且在后续快速查找使用的情景(快速判断一个元素是否出现集合里的时候)就是使用哈希表方法的时机。相关的容器和数据结构包括set,map和数组
class Solution {
public:
bool isAnagram(string s, string t) {
if(s.empty() || t.empty() || s.size() != t.size()){
return false;
}
unordered_map<char,int> sDataMap;
unordered_map<char,int> tDataMap;
for(char i : s){
if(sDataMap.count(i) == 0){
sDataMap.insert(pair<char,int>(i,1));
}else{
unordered_map<char,int>::iterator it = sDataMap.find(i);
(it->second)++;
}
}
for(char i : t){
if(tDataMap.count(i) == 0){
tDataMap.insert(pair<char,int>(i,1));
}else{
unordered_map<char,int>::iterator it = tDataMap.find(i);
(it->second)++;
}
}
for(auto it : sDataMap){
if(tDataMap.count(it.first) <= 0){
return false;
}
if(tDataMap.find(it.first)->second != it.second){
return false;
}
}
return true;
}
};
上述代码其实就是把两个字符串从头到尾遍历一遍,所有字符和出现次数组成键值对塞入两个字符串各自对应的unordered_map里,然后比较两个unordered_map是否有未出现的键值或是出现次数对不上的数值。需要注意的是一些边界情况,例如初始字符串为空和字符串间长度不一的情况,直接处理。
找交集,是不是也是一个需要快速判断某个元素是否已出现的情景,那就也是哈希表的思路,同时,输出结果元素的出现是唯一的,考虑使用set
容器
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> nums1Set;
unordered_set<int> nums2Set;
vector<int> res;
for(auto i : nums1){
nums1Set.insert(i);
}
for(auto i : nums2){
nums2Set.insert(i);
}
for(auto i : nums1Set){
if(nums2Set.count(i) > 0){
res.push_back(i);
}
}
return res;
}
};
其实就是把两个数组的值各自放进set,然后比较set之间是否有刚好对上的元素,就是交集了
注意看示例,判断不是快乐数时候
n = 2 -> 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 (循环了!!!)
也就是说,如果某个时刻各个位的平方和结果已出现,即可判断非快乐数,拿下!
class Solution {
public:
bool isHappy(int n) {
unordered_set<int> sumSet;
int res = n;
while(1){
if(sumSet.count(res) > 0){
return false;
}
sumSet.insert(res);
string nString = to_string(res);
int sum = 0;
for(int i = 0;i < nString.size();i++){
sum += pow((int)(nString[i] - '0'),2);
}
if(sum == 1){
return true;
}
res = sum;
}
}
};
选取未知大小的数的各个位的值这里,我用的把整数与string互转,直接操作char的ASCII的办法,主打一个好写
这道题如果不是整数数组和target可能取负数,用一个大数组来充当哈希表也可行,这里用的map
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> nums_map;
vector<int> res;
for(int i = 0;i< nums.size();i++){
nums_map.insert(pair<int,int>(nums[i],i));
}
for(int i = 0;i < nums.size();i++){
if(nums_map.count(target-nums[i]) > 0){
if(i == nums_map.find(target-nums[i])->second){
continue;
}
res.push_back(i);
res.push_back(nums_map.find(target-nums[i])->second);
break;
}
}
return res;
}
};
哈希表的解法主要是用来处理需要检查某个元素是否已经出现在集合中的场景,备选的结构包括set,map和数组,像是找交集,找交点,比较异同这种题目来说是一个很好的思考角度。