454. 四数相加 II
题目
https://leetcode.cn/problems/4sum-ii/
题解
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> mp1(nums1.size());
int count = 0;
for(int i = 0;i < nums1.size();i++)
{
for(int j = 0;j < nums2.size();j++)
{
int key = nums1[i] + nums2[j];
mp1[key] ++;
}
}
for(int i = 0;i < nums3.size();i++)
{
for(int j = 0;j < nums4.size();j++)
{
auto temp = mp1.find(-nums3[i] - nums4[j]);
if(temp != mp1.end())
count += temp->second;
}
}
return count;
}
};
注意
1.当map内元素值为int类型或常量时,默认值为0。
当为String类型时,默认值不明,不显示。
383. 赎金信
题目
https://leetcode.cn/problems/ransom-note/
题解
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
if(ransomNote.size() > magazine.size())
return false;
int table[26] = {0};
for(int i = 0;i < magazine.size();i++)
{
table[magazine[i] - 'a']++;
}
for(int i = 0;i < ransomNote.size();i++)
{
table[ransomNote[i] - 'a']--;
if(table[ransomNote[i] - 'a'] < 0)
return false;
}
return true;
}
};
15. 三数之和
题目
https://leetcode.cn/problems/3sum/
题解
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
// 找出a + b + c = 0
// a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.size(); i++) {
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if (nums[i] > 0) {
return result;
}
// 错误去重a方法,将会漏掉-1,-1,2 这种情况
/*
if (nums[i] == nums[i + 1]) {
continue;
}
*/
// 正确去重a方法
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while (right > left) {
// 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组
/*
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
*/
if (nums[i] + nums[left] + nums[right] > 0) right--;
else if (nums[i] + nums[left] + nums[right] < 0) left++;
else {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
// 找到答案时,双指针同时收缩
right--;
left++;
}
}
}
return result;
}
};
注意
1.对a去重时,由于排序后i + 1也是三元组的一份子,因此对nums[i]和nums[i + 1]进行比较去重的话相当于满足“三元组中不能有数值大小相同的元素”,而i- 1是已经使用过的值,不在三元组内,因此对nums[i - 1]和nums[i]进行比较去重相当于满足“不能有重复的三元组”
2.whle取边界条件时可以通过代入的方式进行判断,在本题中,若while的循环条件为(left<= right),则当left==right时还会进入循环,则不满足“三元组不重复”的条件
3.对b和c进行去重时,也需要同i一样判断是否数值相同来进行去重,但是去重逻辑应该放在找到一个三元组之后。
4.找到对应三元组后,还需要对双指针进行处理
四数之和
题目
https://leetcode.cn/problems/4sum/
题解
注意
1.target可能为正可能为负,因此不能同三数之和一样通过nums[i] > 0(此题为nums[i] > target)来进行去重
例子:[-4,-1,0,0],target = -5
2.针对多个数相加的情况,需要强制转换,否则会移除导致报错
(long)nums[j] + nums[left] + nums[right]