代码随想录 (programmercarl.com)
hash表的使用情况:
1.快速判断一个元素是否出现在集合里;
2.判断一个元素是否出现过;
思路:
将26个字母一一对应哈希表的位数
统计s字符串各个字符出现的次数,记录在对应下标的数组中
遍历t字符串各个字符,每遇到一个,将对应下标数组中数值减1
遍历完后,再次对整个数组 进行遍历,判断是否数组的各个数值均为0
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26]={0};
for(int i=0;i<s.size();i++){
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){
return false;
}
}
return true;
}
};
关键:
本题要求,结果各元素唯一,可以无序,所以考虑数组或者hash表,
但本题没有限制数值大小,且若不同数值个数较少,占用数组空间较大浪费,那么考虑哈希,使用结构体set
知识点:用find这个函数,去找str这个序列中的i元素,如果序列中所找的这个元素不存在,就会返回end()。
即:nums_set.find(num)!=nums_set.end() //找到了
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());
}
};
class Solution {
public:
bool isHappy(int n) {
unordered_set<int> set;
while(1){
int sum=getSum(n);
if(sum==1)
return true;
if(set.find(sum)!=set.end())//找到了
return false;
else
set.insert(sum);
n=sum;
}
}
int getSum(int n){
int sum=0;
while(n){
sum+=(n%10)*(n%10);
n=n/10;
}
return sum;
}
};
思考:
看到无限循环,想到sum求和会有重复,可以考虑使用hash判断一个元素是否出现在集合里。
当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
本题需要思考正在遍历所有元素时,当下这个元素之前是否出现过。
- 为什么会想到用哈希表——因为题目要求不能使用两次相同的元素,所以在遍历元素时,需要知道当前元素是否被使用过(出现过);
- 哈希表为什么用map——因为题目要求输出对应元素的下标,所以当进行遍历寻找目标元素组时,要存储元素值和对应的下标,而set只能存放一种数值,map可以两种;
- 本题map是用来存什么的——存储符合要求的元素值和对应的下标;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map;
for (int i=0;i<nums.size();++i) {
auto it = map.find(target-nums[i]);
if (it !=map.end()){
return {it->second,i};
}
map.insert(pair<int,int>(nums[i],i));
}
return {};
}
};