四数相加II:
好好珍惜一下,这是哈希表专题为数不多能用哈希表做的题目。
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。
例如:
输入:
- A = [ 1, 2]
- B = [-2,-1]
- C = [-1, 2]
- D = [ 0, 2]
输出:
2
解释:
两个元组如下:
- (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
- (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
对应力扣454题
这题只用输出个数就行,不用输出对应的数字,可以用map来做,基本思路是用map存nums1+nums2的数,用两个for循环遍历nums1+nums2,有重复的就将value+1,表示有n个nums1+nums2等于map中对应的数,之后遍历nums3+nums4,如果nums3+nums4等于-(nums1+nums2)在map中有对应的,计数+n即可。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> map;
int k=0;
for(int i=0;i<nums1.size();i++)
{
for(int j=0;j<nums2.size();j++)
{
if(map.find(nums1[i]+nums2[j])!=map.end())
map.find(nums1[i]+nums2[j])->second++;
else
map.insert({nums1[i]+nums2[j],1});
}
}
for(int i=0;i<nums3.size();i++)
{
for(int j=0;j<nums4.size();j++)
{
if(map.find(0-nums3[i]-nums4[j])!=map.end())
k=k+((map.find(0-nums3[i]-nums4[j]))->second);
}
}
return k;
}
};
赎金信
最简单的一集,对应力扣383题,和242题是一个思路,用数组哈希即可。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int res[26]={0};
for(int i=0;i<magazine.size();i++)
{
res[magazine[i]-'a']++;
}
for(int i=0;i<ransomNote.size();i++)
{
res[ransomNote[i]-'a']--;
}
for(int i=0;i<26;i++)
{
if(res[i]<0)return 0;
}
return 1;
}
};
三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
这题跟哈希表好像没啥关系,是用双指针来做的,不要看跟四数相加很像,其实完全不一样,对应力扣15题。
注意去重操作,
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
这一步很关键。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if(nums[i]>0)return res;
if(i>0&&nums[i]==nums[i-1])continue;
int left=i+1,right=nums.size()-1;
while(left<right)
{
if(nums[i]+nums[left]+nums[right]==0)
{res.push_back(vector<int>{nums[i], nums[left], nums[right]});
while(left < right &&nums[left]==nums[left+1])left++;
while(left < right &&nums[right]==nums[right-1])right--;
left++;
right--;}
else if(nums[i]+nums[left]+nums[right]<0)left++;
else
right--;
}
}
return res;
}
};
四数之和:
题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
对应力扣18题
这题跟三数之和类似,使用两层for循环+双指针就能解决问题,但是要注意target可能为负数,比如说targer=-5,数组为[-4,-1,0,0],这是满足条件的,所以不能
if(nums[i]>0)return res;
代码如下:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if(nums[i]>target&&target>=0)break;
if(i>0&&nums[i]==nums[i-1])continue;
for(int j=i+1;j<nums.size();j++)
{ if(nums[j]==nums[j-1]&&j>i+1)continue;
if(nums[i]+nums[j]>target&&nums[i]+nums[j]>=0)break;
int left=j+1,right=nums.size()-1;
while(left<right)
{
if((long)nums[i]+nums[j]+nums[left]+nums[right]<target)left++;
else if((long)nums[i]+nums[j]+nums[left]+nums[right]>target)right--;
else
{res.push_back({nums[i],nums[j],nums[left],nums[right]});
while(left<right&&nums[left]==nums[left+1])left++;
while(left<right&&nums[right-1]==nums[right])right--;
left++;right--;
}
}
}
}
return res;
}
};
最后两个好像和哈希没啥关系哈,结束!