454. 4Sum II
Sum of numbers from different arrays equals to 0, each number from each diff array
Core Idea: Bucket
unordered_map<sum, number of times> bucket
record sum from first two array++bucket[nums1[i] + nums[j]]
emplace_back() of sum of each elem from array a and each from array bif(buckect[0 - nums3[i] - num4[j]]) count += bucket[0 - nums3[i] - num4[j]]
check if 0 minus one elem from array c and one from array d exists, if so, add the number of times appeared to the results
383.Ransom Note
Check if ransomNote can be constructed by using the letters from magazine
Core Idea: Bucket the steps are the same as above 454
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char, int> bucket;
for(auto c : magazine)
{
++bucket[c];
}
for(auto c : ransomNote)
{
if(--bucket[c] < 0)
return false;
}
return true;
}
18. 4Sum And 15. 3Sum
Sum of numbers in the same array, but not same index
Core Idea: Double-Pointers Double-Pointers narrows down the range to find the target, which will get rid of time to remove duplications
- sort the vector so we can apply double-pointers
- iterate
i = 0
,j = i + 1
(3Sum won’t contain this),left point = j + 1, right = last index
- check the sum, move pointers with checking duplications
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> quadruplets;
if(nums.size() < 4)
return quadruplets;
sort(nums.begin(), nums.end());
for(int a = 0; a < nums.size() - 3; ++a)
{
// ignore duplication
if(a > 0 && nums[a - 1] == nums[a])
continue;
// sum of four smallest num > target => break
if((long)nums[a] + nums[a + 1] + nums[a + 2] + nums[a + 3] > target)
break;
// sum of current a with three largest nums < target, a needs to get bigger => continue
if((long)nums[a] + nums[nums.size() - 1] + nums[nums.size() - 2] + nums[nums.size() - 3] < target)
continue;
for(int b = a + 1; b < nums.size() - 2; ++b)
{
if(b > a + 1 && nums[b - 1] == nums[b])
continue;
if((long)nums[a] + nums[b] + nums[b + 1] + nums[b + 2] > target)
break;
if((long)nums[a] + nums[b] + nums[nums.size() - 1] + nums[nums.size() - 2] < target)
continue;
int left = b + 1;
int right = nums.size() - 1;
while(left < right)
{
if((long)nums[left] + nums[right] + nums[a] + nums[b] < target)
++left;
else if((long)nums[left] + nums[right] + nums[a] + nums[b] > target)
--right;
else
{
quadruplets.emplace_back(vector<int>{nums[a], nums[b], nums[left++], nums[right--]});
// ignore duplication
while(left < right && nums[left] == nums[left - 1]) ++left;
while(right > left && nums[right] == nums[right + 1]) --right;
}
}
}
}
return quadruplets;
}