找一个数是否出现过或一个数是否在集合中的时候就要想到用哈希表法
242有效的字母异位词
bool isAnagram(string s, string t) {
int table[26];
for(char i:s) {
table[i-'a'] +=1;
}
for(char i:t) {
table[i-'a'] -=1;
}
for(int i:table) {
if(i!=0)return false;
}
return true;
}
349两个数组的交集
用unorderedset来解决
利用其去重的特性,且底部实现为哈希表所以读写速率快
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> num1(nums1.begin(),nums1.end());
unordered_set<int> result;
for(int i:nums2) {
if(num1.find(i) != num1.end()) {
result.insert(i);
}
}
return vector<int>(result.begin(),result.end());
}
1两数之和
又要找数又要找下标所以利用map,不需要有序所以利用unorderedmap,底部实现是用哈希表。
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> num_map;
for(int i=0;i<nums.size();i++) {
unordered_map<int,int>::iterator iter = num_map.find(target-nums[i]);
if(iter!=num_map.end()) {
return vector<int>{iter->second,i};
}
num_map.insert(make_pair(nums[i],i));
}
return {};
}
454四数之和
创建unordered_map,先遍历第一第二个数组,key为和的值value为出现的次数。然后再遍历第三第四数组,查找value为他们和的负值的key,找到了就增加count。,
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> umap;
for(int a:nums1) {
for(int b:nums2) {
umap[a+b]++;
}
}
int count = 0;
for(int c:nums3) {
for(int d:nums4) {
if(umap.find(0-(c+d))!=umap.end()) {
count += umap[0-(c+d)];
}
}
}
return count;
}
383赎金信
我的暴力解法
//暴力解法
bool canConstruct(string ransomNote, string magazine) {
map<int,int> Note;
int count = 0;
for(char i:ransomNote) {
Note[i]++;
count++;
}
for(char i:magazine) {
if(Note.find(i) != Note.end()) {
if(Note.find(i)->second>0) {
Note[i]--;
count--;
}
}
}
if(count == 0) {
return true;
}
return false;
}
数组做哈希表
//用数组做哈希表
bool canConstruct(string ransomNote, string magazine) {
//因为只有小写字母 所以用数组比较好
int alpha[26]={0};
if(ransomNote.size()>magazine.size()) {
return false;
}
for(char i:magazine) {
alpha[i-'a']++;
}
for (char i:ransomNote) {
alpha[i-'a']--;
if(alpha[i-'a']<0) {
return false;
}
}
return true;
}
三数之和
哈希表法(做法复杂)
推荐使用双指针法
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-1;i++) {
if(nums[i]>0) break;
if(i>0 && nums[i]==nums[i-1])continue;
unordered_set<int> set;
int c;
for(int j=i+1;j<nums.size();j++) {
if(j>i+2 && nums[j-1]==nums[j-2] && nums[j]==nums[j-1]) {
continue;
}
c = 0-(nums[i]+nums[j]);
if(set.find(nums[j]) != set.end()) {
result.push_back({nums[i],nums[j],c});
set.erase(c);
}
else {
set.insert(c); //为什么存c不行?这个c是想要的值,不代表实际存在的值
}
}
}
return result;
}
};
双指针法
//双指针法
class Solution1 {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++) {
if(nums[i]>0)return result;
if(i>0 && nums[i]==nums[i-1])continue;
int left = i+1;
int right = nums.size()-1;
while(left<right) {
int sum = nums[i]+nums[left]+nums[right];
if(sum >0){right--;}
else if(sum<0){left++;}
else {
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
while(right>left && nums[left+1]==nums[left]){left++;}
while(right>left && nums[right-1]==nums[right]){right--;}
left++;
right--;
}
}
}
return result;
}
};