242.有效的字母异位词
思路:创建一个数组作为哈希表,将s字符的元素对应到哈希表中(26个字母对应26个元素,有哪个字母该元素就+1),再将t字符串的元素对应到哈希表中(有哪个字母,对应的数组元素就-1),最后检查,如果数组的元素都是0,就输出true,否则输出false
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26]={0}; //创建一个26大小的数组用来存放哈希表
for(int i=0;i<s.size();i++){
record[s[i]-'a']++; //s[i]-'a'就是对应的第几个下标
}
for(int j=0;j<t.size();j++){
record[t[j]-'a']--;
}
//判断数组中元素个数是否都是0
for(int k=0;k<26;k++){
if(record[k]!=0)
return false;
}
return true;
}
};
349. 两个数组的交集
知道哈希表的大小是,数组当哈希表时,没有限制数值的大小时,使用set作为哈希表
关于set,C++ 给提供了如下三种可用的数据结构:
- std::set
- std::multiset
- std::unordered_set
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
思路:
- 将数组1转化为哈希表,用std::unordered_set,给哈希表降重
- 遍历数组2,查询数组2中元素是否在哈希表中出现,将出现在哈希表
中的元素放入结果集中 - 将结果集std::unordered_set形式,转化为数组形式
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()){ //在哈希表中寻找数组2的元素
result_set.insert(num); //数组2在哈希表中的元素放入结果集中
}
}
//将结果集转化为数组
return vector<int>(result_set.begin(),result_set.end());
}
};
第202题. 快乐数
class Solution {
public:
//取数值每个位的平方和
int getSum(int n){
int sum=0;
//计算每一个位的平平方和
while(n){
sum+=(n%10)*(n%10);
n=n/10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> set; //存放每次的和
//循环用来判断每次的和是否在哈希表中出现过
while(1){
int sum=getSum(n);
if(sum==1){
return true;
}
//如果sum曾经出现过,就说明陷入无限循环 return false
if(set.find(sum) !=set.end()){
return false;
} else {//如果没有出现过 就放入哈希表中
set.insert(sum);
}
//将sum循环当作下一次的n
n=sum;
}
}
};
1.两数之和
当需要查询一个元素是否出现过,或者一个元素是否出现在一个集合中时,第一时间想到的就是使用哈希表
在哈希表中,使用数组,set,map的区别:
- 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
- set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和y的下标。所以set 也不能用。
- map ,map是一种key value的存储结构,可以用key保存数值,用value再保存数值所在的下标。
思路:在本题,不仅需要知道是否遍历过,还需要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用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++){
//查找是否存在,如果存在iter指向对应的元素 找不到,将指向map的结尾
auto iter=map.find(target-nums[i]);
//如果没有指向结尾 就说明找到对应的元素
if(iter!=map.end()){
return {iter->second,i};
}
//如果 find() 函数未找到对应的元素,将当前元素和它的索引插入到 map 中,使得后续的元素可以通过此元素来进行查找。
map.insert(pair<int,int>(nums[i],i));
}
return {};
}
};