中国城乡建设经济研究所 网站,青海网站建设公司,开发一个交友app需要多少钱,企业如何开展网络营销当我们遇到了要快速判断一个元素是否出现集合里的时候#xff0c;就要考虑哈希法。 哈希碰撞#xff1a;1、拉链法#xff1a;其实拉链法就是要选择适当的哈希表的大小#xff0c;这样既不会因为数组空值而浪费大量内存#xff0c;也不会因为链表太长而在查找上浪费太多时… 当我们遇到了要快速判断一个元素是否出现集合里的时候就要考虑哈希法。 哈希碰撞1、拉链法其实拉链法就是要选择适当的哈希表的大小这样既不会因为数组空值而浪费大量内存也不会因为链表太长而在查找上浪费太多时间。 2、线性探测法 例如冲突的位置放了小李那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize 要不然哈希表上就没有空置的位置来存放 冲突的数据了。、 class Solution {
public:bool isAnagram(string s, string t) {if(s.size()!t.size()) return false;vectorint res(26,0);for(int i0;is.size();i){res[s[i]-a];}for(int i0;it.size();i){res[t[i]-a]--;}for(int i0;i26;i){if(res[i]) return false;}return true;}
};
就是判断出现的次数加上字符串出现次数不多直接的想法是用哈希表一遍ac.
进阶: 如果输入字符串包含 unicode 字符怎么办你能否调整你的解法来应对这种情况
这里的空间复杂度是O126相比n很小所以是O1。 可以考虑练习使用set如果没有限制数值的大小就无法使用数组来做哈希表了。看了题解才写的主要是不熟悉unordered_set的写法。
class Solution {
public:vectorint intersection(vectorint nums1, vectorint nums2) {unordered_setint res;vectorint ans;for(int i0;inums1.size();i){res.insert(nums1[i]);}for(int i0;inums2.size();i){if(res.find(nums2[i])!res.end()){ans.push_back(nums2[i]);}}unordered_setint tmpunordered_setint(ans.begin(),ans.end());;return vectorint(tmp.begin(),tmp.end());}
};
题解写法
class Solution {
public:vectorint intersection(vectorint nums1, vectorint nums2) {unordered_setint result_set; // 存放结果之所以用set是为了给结果集去重unordered_setint nums_set(nums1.begin(), nums1.end());for (int num : nums2) {// 发现nums2的元素 在nums_set里又出现过if (nums_set.find(num) ! nums_set.end()) {result_set.insert(num);}}return vectorint(result_set.begin(), result_set.end());}
};
拓展
那有同学可能问了遇到哈希问题我直接都用set不就得了用什么数组啊。
直接使用set 不仅占用空间比数组大而且速度要比数组慢set把数值映射到key上都要做hash计算的。
不要小瞧 这个耗时在数据量大的情况差距是很明显的。 class Solution {
public:bool isHappy(int n) {unordered_setlong long res;int ans0;while(n!1){ans0;while(n){int tmpn%10;ans(tmp*tmp);n/10;}if(ans1) return true;if(res.find(ans)!res.end()) return false;res.insert(ans);nans;}return true;}
};
空间复杂度和时间复杂度都是ologn
一遍ac。就是结果会循环出现判断出现出现过的结果就判断为false如果出现1就判断为true。 class Solution {
public:vectorint twoSum(vectorint nums, int target) {unordered_mapint,int ans;for(int i0;inums.size();i){if(ans.find(target-nums[i])!ans.end()){return {ans[target-nums[i]],i};}ans[nums[i]]i;// ans.insert(pairint,int(nums[i],i));}return {};}
};
看了map的使用方法一遍ac。只会出现一种情况想到哈希。知道目标值和遍历数组的每个数值的情况下如果需要的另外一个数值已经插入到map中就返回该数映射的下标和当前下标。
首先我再强调一下 什么时候使用哈希法当我们需要查询一个元素是否出现过或者一个元素是否在集合里的时候就要第一时间想到哈希法。
下面是题解写法
class Solution {
public:vectorint twoSum(vectorint nums, int target) {std::unordered_map int,int map;for(int i 0; i nums.size(); i) {// 遍历当前元素并在map中寻找是否有匹配的keyauto iter map.find(target - nums[i]); if(iter ! map.end()) {return {iter-second, i};}// 如果没找到匹配对就把访问过的元素和下标加入到map中map.insert(pairint, int(nums[i], i)); }return {};}
}; 空间复杂度和时间复杂度是On。
map.insert 可以加入pair的数据结构。map.find用来查找元素。