关于哈希表:
在要求快速查询,最小时间复杂度 O(1) 场景时候,需要想到哈希表。
(查的快,还需要对查询出的数据有排序需求时,要想到红黑树)
哈希表(感觉叫散列表更加直观):原始数据通过映射关系(哈希函数,一般是除留余数法),得到一个在表中离散的位置,映射过程中可能发生两个元素的位置相同的情况(哈希碰撞),降低哈希碰撞发生概率有两种设计:
1.让哈希表的长度等于素数;
2.哈希表已经占用的桶的个数/哈希桶的总个数>0.75(装载因子loadfactor)时,要扩容哈希表(扩容大小也为素数大小,例如从7扩容到23),扩容后所有的元素在哈希表中的位置都要重新确定,因此扩容的代价还是很大的。
哈希碰撞的解决办法有两种,线性探测法和链地址法
242. 有效的字母异位词 - 力扣(LeetCode)
数组就是简单的哈希表 ,当题目的数据有范围时(例如这道题,英文小写字母的类型是有限的,只有26种),要想到利用26个字母的ASCII码。
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int>table(26,0);
for(int i=0;i<s.size();i++){
table[s[i]-'a']++;
}
for(int i=0;i<t.size();i++){
table[t[i]-'a']--;
}
for(int i=0;i<26;i++){
if(table[i]!=0){
return false;
}
}
return true;
}
};
349. 两个数组的交集 - 力扣(LeetCode)
这道题的描述是很经典的,输出要求去重、无序,自然想到要使用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());
//遍历nums2的元素,并将每次遍历的元素赋值给num
for(int num:nums2){
//如果找到了元素,它会返回一个指向该元素的迭代器;
//如果没有找到,它会返回一个指向集合末尾的迭代器。
if(nums_set.find(num)!=nums_set.end()){
result_set.insert(num);
}
}
//最后将set转成vector
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){
//利用unordered_set去重的特点
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};
202. 快乐数 - 力扣(LeetCode)
需要注意对数值各位上单数操作的掌握。
class Solution {
public:
int getNum(int n){
int sum=0;
while(n){
sum+=(n%10)*(n%10);
n/=10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int>result_set;
while(1){
int sum=getNum(n);
if(sum==1){
return true;
}
//如果找到了元素,它会返回一个指向该元素的迭代器;
//如果没有找到,它会返回一个指向集合末尾的迭代器。
else if(result_set.find(sum)!=result_set.end()){
return false;
}
else {
result_set.insert(sum);
}
n=sum;
}
}
};
1. 两数之和 - 力扣(LeetCode)
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的
- map中的key和value用来存什么的
因为要遍历数组,查询符合题目要求的元素,所以想到用哈希表;元素大小不确定,返回值要求是元素的对应下标,所以不使用set(只有value),而选择使用map(value,key),这道题的map用来存放已经访问过的元素。key用来存放数组元素的值,value用来存放下标。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int ,int >hash;
for(int i;i<nums.size();i++){
auto iter=hash.find(target-nums[i]);
//不等于末尾迭代器,说明找到了该元素
if(iter!=hash.end()){
return {iter->second,i};
}
//没找到,就把查询过的元素值和索引加到map中
hash.insert(pair<int,int>(nums[i],i));
}
return {};
}
};

166

被折叠的 条评论
为什么被折叠?



