1.有效的字母异位词
class Solution {
public:bool isAnagram(string s, string t) {unordered_map<char,int> mymap;for(auto c:s){mymap[c]=mymap[c]+1;}for(auto c:t){mymap[c]=mymap[c]-1;}for(auto item:mymap){if(item.second!=0){return false;}}return true;}
};
2.两个数组的交集
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> myset;for(int num:nums1){myset.insert(num);}unordered_set<int> result_set;for(int num:nums2){if(myset.count(num)>0){result_set.insert(num);}}vector<int> result(result_set.begin(),result_set.end());return result;}
};
3.快乐数
不能成为快乐数 即使之前拼接成的sum再次出现过 用set收集没有出现过的sum即可 一旦之前出现过直接返回false
#include <stdlib.h>
#include <stdio.h>
class Solution {
public:bool isHappy(int n) {string str = to_string(n);unordered_set<int> myset;while(true){int sum=0;for(char c:str){sum = pow(c-'0',2)+sum;}if(sum==1){return true;}if(myset.count(sum)>0){return false;}myset.insert(sum);str = to_string(sum);}return false;}
};
4.两数之和
就是一个用map储存已经遍历过的值 unordered_map<value,index> mymap; 遍历过程中 如果map中存在和当前遍历元素和是target 直接返回即可(题目说 答案唯一)
class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> mymap;for(int i=0;i<nums.size();i++){if(mymap.count(target-nums[i])>0){return {mymap[target-nums[i]],i};}else{mymap[nums[i]]=i;}}return {};}
};
5.四数相加II
将四数相加分解成 两个集合相加 每个集合里面有两个数组
class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int,int> mymap;for(int i=0;i<nums1.size();i++){for(int j=0;j<nums2.size();j++){mymap[nums1[i]+nums2[j]] = mymap[nums1[i]+nums2[j]]+1;}}// for(auto item:mymap){// cout<<"first:"<<item.first<<" seconde:"<<item.second<<endl;// }cout<<endl;int count =0;for(int k=0;k<nums3.size();k++){for(int l=0;l<nums4.size();l++){int target= 0 -nums3[k]-nums4[l];if(mymap.count(target)>0){count=count+mymap[target];}}}return count;}
};
7.赎金信
主要思路 用map储存magazine每个元素以及统计元素出现的次数 遍历ransomNote 判断map是否含有该元素以及剩余次数是否还有
class Solution {
public:bool canConstruct(string ransomNote, string magazine) {unordered_map<char,int> mymap;for(auto c:magazine){mymap[c]=mymap[c]+1;}for(auto c:ransomNote){if(mymap.count(c)==0||mymap[c]<=0){return false;}else{mymap[c]=mymap[c]-1;}}return true;}
};
8.三数之和
这里不适用哈希的原因是去重非常复杂 现对原先数组进行排序 使用双指针去重则非常简单
去重
第一个位置去重
if(i-1>=0&&nums[i]==nums[i-1]){continue;}
第二个元素以及第三个元素去重
while(j+1<nums.size()&&nums[j]==nums[j+1]){j++;}j++;while(k-1>=0&&nums[k]==nums[k-1]){k--;}
完整代码
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end(),[](int num1,int num2){return num1<num2;});vector<vector<int>> result;for(int i=0;i<nums.size();i++){if(i-1>=0&&nums[i]==nums[i-1]){continue;}int j=i+1;int k = nums.size()-1;int target = 0- nums[i];while(j<k){if(nums[j]+nums[k]>target){k--;}else if(nums[j]+nums[k]<target){j++;} else if(nums[j]+nums[k]==target){result.push_back({nums[i],nums[j],nums[k]});while(j+1<nums.size()&&nums[j]==nums[j+1]){j++;}j++;while(k-1>=0&&nums[k]==nums[k-1]){k--;}k--;}}}return result;}
};
9.四数之和
这里就是固定a,b的位置 然后双指针移动c和d
class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(),nums.end(),[](int num1,int num2){return num1<num2;});vector<vector<int>> result;for(int a=0;a<nums.size();a++){if(a-1>=0&&nums[a]==nums[a-1]){continue;}for(int b=a+1;b<nums.size();b++){if(b-1>=a+1&&nums[b]==nums[b-1]){continue;}// 这里这么些 是因为测试用例里面有int最小值 防止溢出long int newtargert = (long int)target-(long int)nums[a]-(long int)nums[b];int c = b+1;int d = nums.size()-1;// cout<<" a:"<<a<<" b:"<<b<<" c:"<<c<<" d:"<<d<<endl;while(c<d){// cout<<" nums[c]:"<<nums[c]<<" nums[d]:"<<nums[d]<<" newtargert:"<<newtargert<<endl;if(nums[c]+nums[d]>newtargert){d--;}else if(nums[c]+nums[d]<newtargert){c++;} else{result.push_back({nums[a] ,nums[b] ,nums[c], nums[d]});while(c+1<nums.size()&& nums[c]==nums[c+1]){c++;}c++;while(d-1>=0&&nums[d]==nums[d-1]){d--;}d--;}}}}return result;}
};