简介
对哈希表和哈希映射的一些总结
哈希表
242.有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
示例 2: 输入: s = "rat", t = "car" 输出: false
说明: 你可以假设字符串只包含小写字母。
这题的关键就是将26个字母转化为26个数,利用ASCII的连续编码映射为单一的连续的key。
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for (int i = 0; i < s.size(); i++) {
// 从0开始记录26个小写字母,减去a得到差值,记录次数即可
record[s[i] - 'a']++;
}
for (int i = 0; i < t.size(); i++) {
// 从0开始记录26个小写字母,减去a得到差值,记录次数即可
record[t[i] - 'a']--;
}
for (int i = 0; i <26; i++) {
if(record[i]!=0)
{return false;}
}
return true;
}
};
349. 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是
唯一的。我们可以不考虑输出结果的顺序 。
(1)第五句的定义,直接将数组转化为了哈希表
(2)find返回的是key值对应的迭代器,如果没有,返回的是hash.end(),尾部的迭代器(内部是空的);
(3)construct<data.type>function_name(intput)
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
unordered_set<int> nums_set(nums1.begin(), nums1.end());// 这个定义记一下 直接不知道size的情况下初始化数组s1成为集合
for(int i:nums2)
{
if(nums_set.find(i)!=nums_set.end()) //查找以值为 key 的元素,如果找到,则返回一个指向该元素的正向迭代器;反之,则返回一个指向容器中最后一个元素之后位置的迭代器(如果 end() 方法返回的迭代器
result_set.insert(i);
}
return vector<int>(result_set.begin(),result_set.end()); // 这个vec居然会自己遍历输出
}
};
202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
[快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果可以变为 1,那么这个数就是快乐数。
示例:
输入:19 输出:true
解释:1^2 + 9^2 = 82 8^2 + 2^2 = 68 6^2 + 8^2 = 100 1^2 + 0^2 + 0^2 = 1
注意点:
(1)while(1)进入死循环,函数最后的return就省略了(见倒数第三行)
(2)用到的函数写上面,或者先声明
//求和的过程中,sum可能会重复出现,这对解题很重要!如果重复了就是return
class Solution {false, 否则一直找到sum为1为止。
public:
int sum_squre(int n)
{
int sum=0;
while(n!=0)
{
sum+=(n%10)*(n%10);
n = n/10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int>happy;
while(1){
if(n==1) return true;
int next = sum_squre(n);
if(happy.find(next)!=happy.end())
{
return false;
}
else
{
happy.insert(next);
n = next;// 更新n值
}
}
// 这里不好return,但是加上了 while(1){}
居然就可以不return,因为程序到while(1)就死循环了,不会下来了
}
};
哈希映射
1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那
两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
(1) hash_map定义是{key, value}
(2) map_name.find(x)返回的是key值的迭代器
(3) 通过key找value: map_name[key];通过value找key:利用iterator it对象遍历哈希表
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int>sum;
int flag=0;
for(int i=0;i<nums.size();i++)
{
int match = target - nums[i];
if(sum.find(match)!=sum.end())//这里find的只能是key值
{
return {sum[match],i};// hash_map知道key得到value的方法
}
//
//通过value找 key
// for(std::map<int,char>::iterator it = aMap.begin();it!=aMap.end();it++)
// {
// if(it->second==value)
// cout<<"通过value: "<<value<<" 找到的key:"<<it->first<<endl;
else
{
sum.insert({nums[i],flag});// {key,value}
flag++;
}
}
return {}; //还真不知道为啥行
}
};