代码随想录算法训练营Day5 | 242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和
哈希表知识基础详见代码随想录。
哈希表常用于判断元素是否在集合中,常用的数据结构有:
数组
集合set
映射map
要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset。
242.有效的字母异位词 题目链接
数组就是一个简单的哈希表,映射的是26个字母在字符串中出现的次数,s串时+1,t串时-1,最后判断数组是否为0即可。
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
int n1 = s.size();
int n2 = t.size();
for(int i=0;i<n1;i++){
record[s[i]-'a']++;
}
for(int i=0;i<n2;i++){
record[t[i]-'a']--;
}
for(int i=0;i<26;i++){
if(record[i]!=0){
return false;
}
}
return true;
}
};
要注意的是,使用数组作为哈希表的前提是限制了数值的大小。
349.两个数组的交集 题目链接
方法一:数组
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
int hash[1001] = {0};
for(int num : nums1){
hash[num] = 1;
}
for(int num : nums2){
if(hash[num]==1){
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};
注意for(:)的用法,以及vector语句的使用。
方法二: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()){
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};
注意find()返回的是被查找元素的迭代器,如果未找到则返回set.end()。
202.快乐数 题目链接
该题的核心是判断sum是否重复出现。注意取一个数的各个位置上的数值的操作。
class Solution {
public:
int getsum(int n){
int sum = 0;
while(n){
sum += (n%10)*(n%10);
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.两数之和 题目链接
本题需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,即是否出现在这个集合。我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,需要使用 key-value结构来存放,key来存元素,value来存下标,那么使用map正合适。
map中的存储结构为 {key:数据元素,value:数组元素对应的下表}
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]);
if(iter != map.end()){
return {iter->second,i};
}
map.insert(pair<int,int>(nums[i],i));
}
return {};
}
};
注意map结构的操作语句写法,其中iter->second是指迭代器指向的value值,iter->first是指迭代器指向的key值。