哈希表系列
242. 有效的字母异位词
s与t都仅包含小写字母,可以使用数组存储二十六个英文字母出现的次数
class Solution {
public:
bool isAnagram(string s, string t) {
int abc[26] = {0};
for(int i=0;i<s.size();i++) {
abc[s[i]-'a']++;
}
for(int i=0;i<t.size();i++) {
abc[t[i]-'a']--;
}
for(int i=0;i<26;i++) {
if(abc[i]!=0)
return false;
}
return true;
}
};
unordered_map与unordered_set的区别与联系:
相同点,都是存储不重复的元素
不同点,unordered_map存的是键值对,unordered_set存的是单个的值
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> us;
unordered_set<int> us_nums2(nums2.begin(),nums2.end());
for(int i=0;i<nums1.size();i++) {
if(us_nums2.find(nums1[i]) != us_nums2.end()) {
us.insert(nums1[i]);
}
}
return vector<int>(us.begin(),us.end());
}
};
使用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;
}
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> umap;
for(int i=0;i<nums.size();i++) {
auto it = umap.find(target-nums[i]);
if(it != umap.end())
return {it->second,i};
umap.insert(pair<int,int>(nums[i],i));
}
return {};
}
};
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int,int> umap;
for(int a:A) {
for(int b:B) {
umap[a+b]++;
}
}
int count =0;
for(int c : C) {
for(int d : D) {
if(umap.find(0-(c+d))!=umap.end()) {
count += umap[0-c-d];
}
}
}
return count;
}
};
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int size = nums.size();
if(size<3)
return {};
vector<vector<int>> res;
sort(nums.begin(),nums.end());
for(int i=0;i<size;i++)
{
if(nums[i]>0)
return res;
if(i>0 && nums[i]==nums[i-1])
continue;
int left = i+1;
int right = size-1;
while(left<right)
{
if(nums[left]+nums[right] > -nums[i]) //两数之和大,右指针向左移
right--;
else if(nums[left]+nums[right] < -nums[i]) //两数之和小,左指针向右移
left++;
else{
//找到了就把他加进去,创建一个临时的一维数组,加入到二维数组中的一项
res.push_back(vector<int>{nums[i],nums[left],nums[right]});
left++;
right--;
//去重,不考虑重复元素
while(left<right && nums[left]==nums[left-1])
left++;
while(left<right && nums[right]==nums[right+1])
right--;
}
}
}
return res;
}
};
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = {0};
for(int i=0;magazine[i]!='\0';i++)
{
record[magazine[i]-'a']++;
}
for(int i=0;ransomNote[i]!='\0';i++)
{
if(record[ransomNote[i]-'a']!=0)
record[ransomNote[i]-'a']--;
else if(record[ransomNote[i]-'a']==0)
return false;
}
return true;
}
};
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int k=0;k<nums.size();k++)
{
//剪枝
if(nums[k]>target && nums[k]>=0) //排除和为负数而漏掉解
break;
//对nums[k]去重
if(k>0 && nums[k] == nums[k-1]) //确保k从第二项开始,有前一项可以比较
continue;
for(int i = k+1;i<nums.size();i++)
{
//剪枝*2
if(nums[i]+nums[k]>target && nums[k]+nums[i] >=0)
break;
//从第二个开始判断,是否与前一个值相同
if(i>k+1 && nums[i] == nums[i-1]) //确保i从第二项开始,有前一项可以比较
continue;
int left = i+1, right = nums.size()-1; //经典双指针法
while(left < right)
{
if((long) nums[k]+nums[i]+nums[left]+nums[right] > target) //大了right往左移
right--;
else if((long) nums[k]+nums[i]+nums[left]+nums[right] < target) //小了left往右移
left++;
else{
result.push_back({nums[k],nums[i],nums[left],nums[right]}); //找到之后用push_back把一维数组的三个值作为二维的一项装入
while(right > left && nums[right] == nums[right-1]) //去重
right--;
while(right > left && nums[left] == nums[left+1]) //去重
left--;
right--;
left++;
}
}
}
}
return result;
}
};