哈希表:
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法
题目:242.有效的字母异位词
将字母的ASCII码映射到数组里,记录字母出现的次数。较简单。
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']--;
}
int flag = 1;
for(int i = 0; i < 26; i++){
if(hash[i] != 0){
flag = 0;
return false;
}
}
return true;
}
};
题目:349.两个数组的交集(unordered_set)(set)
使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
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());
for(int num : nums2){
if(nums_set.find(num) != nums_set.end())
//find函数可以用于查找元素。find(key)查找key是否存在,如果存在,返回该元素的迭代器,如果不存在,返回set.end()
result_set.insert(num);
}
return vector<int>(result_set.begin(), result_set.end());
}
};
解释:
1.set容器的初始化
2.set.find()函数:
3.set.insert()函数
set.insert()怎样给传进去的参数分配键对值?
4.容器之间的相互转换。
用数组哈希数组:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
int hash[1001] = {0};
for(int num : nums1){
hash[num] = 1;
}
for(int num : nums2){
if(hash[num]){
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
题目:202.快乐数
尝试解答:
1.编写函数,作为循环体的一部分,判断本次循环的数是不是快乐数。
2.循环体中进行判断,可能出现以下几种情况:
各位数平方和等于1,是快乐数,true。
各位数平方和不等于1,且在set里出现过,满足题目描述无限循环的“非快乐数”,false
各位数平方和不等于1,尚且没在set里出现过,存入set.
3.要注意以上三步的顺序,第一次写就是顺序错了所以测试过不了。
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;
}
if(set.find(sum) != set.end()){;
return false;
}else{
set.insert(sum);
}
n = sum;
}
}
};
题目:1.两数之和
尝试解答:
遍历,用target减去本次遍历到数,在set里查询是否被存入过,如果有则说明找到了这两个数,需要返回数组下标。理论成立。但存在的疑惑是:1.本题对使用哪种哈希表有没有要求?2.返回的
思路:
1.什么时候用哈希表:当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
2.用数组、map、还是set:需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适。这道题目中并不需要key有序,选择std::unordered_map 效率更高!
问题:对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++){
auto iter = map.find(target - nums[i]); //iter作为匹配对
if(iter != map.end()){
return {iter->second, i}; //second是什么?
}
map.insert(pair<int, int>(nums[i], i));
//存入匹配对:pair(<int, int>(nums[i], i))
}
return {};
}
};
。