您现在的位置是:首页 >其他 >代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202.快乐数 1. 两数之和网站首页其他
代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202.快乐数 1. 两数之和
简介代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202.快乐数 1. 两数之和
目录
哈希结构
数组 / set(集合) / map(映射)
set(集合) 的底层实现及优缺点——
集合 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::set | 红黑树 | 有序 | 否 | 否 | O(log n) | O(log n) |
std::multiset | 红黑树 | 有序 | 是 | 否 | O(logn) | O(logn) |
std::unordered_set | 哈希表 | 无序 | 否 | 否 | O(1) | O(1) |
map(映射) 的底层实现及优缺点——
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::map | 红黑树 | key有序 | key不可重复 | key不可修改 | O(logn) | O(logn) |
std::multimap | 红黑树 | key有序 | key可重复 | key不可修改 | O(log n) | O(log n) |
std::unordered_map | 哈希表 | key无序 | key不可重复 | key不可修改 | O(1) | O(1) |
LeeCode 242.有效的字母异位词
思路:
定义数组 record 记录字符串 s 中字符出现的次数,将 s 中的字符映射哈希表的数值做 +1 操作,遍历字符串 t ,对t中的字符映射哈希表的数值做 -1 操作,最后遍历数组 record ,若数组元素全为 0 ,则 return true ,反之 return false 。
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;
}
};
LeeCode 349. 两个数组的交集
思路:
将 nums1 数组的元素利用 unordered_set 数据结构进行去重转化后与 nums2 数组元素进行比较,若有相同元素,将其存储在 result_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());
//对于数组nums2中的每个元素,将其赋值给变量num,然后执行循环中的语句
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:
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());
}
};
LeeCode 202.快乐数
思路:
求和的时候若 sum 重复出现,则应 return false , 而判断求和是否重复出现,就需要用到unordered_set。
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;
}
}
};
LeeCode 1. 两数之和
思路:
map 用来存放访问过的元素, map 中的存储结构为 { key:数据元素,value:数组元素对应的下标 },在遍历数组时,向 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]);
if(iter != map.end()){
return{iter->second,i};
}
map.insert(pair<int,int>(nums[i],i));
}
return{};
}
};
总结
1.需要查询一个元素是否出现过,或者需要快速判断一个元素是否出现集合里的时候,考虑哈希法。
2.如果哈希值比较少、特别分散、跨度非常大,使用数组造成空间浪费。
3.理解思想和写出来能运行通过的代码之间的差距对现在的我来说感觉就像鸿沟,有些语句甚至是之前完全没见过的。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。