无重,只有一个结果,而不需要顺序执行
查询 target-num[i]; 如果有就返回结果
如果没有,使用一个map承接当前值,
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int ,int>mp;
for(int i=0; i<nums.size(); i++){
if(mp.find(target-nums[i]) != mp.end()) return {mp[target-nums[i]], i};
mp[nums[i]] = i;
}
return{-1, -1};
}
};
- 四数相加 II
而这道题目是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况
将前两个数组的之和 放进map, 遍历后两个数组之和找符合要求的值
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int>mp; // num1 + num2 的和 以及出现次数
for(int i=0; i<nums1.size(); i++){
for(int j =0; j<nums2.size(); j++){
mp[nums1[i] + nums2[j]]++;
}
}
int count = 0;
for(int i=0; i<nums3.size(); i++){
for(int j =0; j<nums4.size(); j++){
if(mp.find(0-nums3[i]-nums4[j])!=mp.end())
count += mp[0-nums3[i] - nums4[j]];
}
}
return count;
}
};
排序 , 然后双指针遍历
因为和为0 不是某个target 所以可以在 第一个数大于0 时提前结束。
注意点:去重
1.最外层循环的去重
2.中间一层循环的去重
疑问:为什么 left参与去重,right不需要
可以写但是没有用,left的去重是寻找下一个不一样的元素,找到之后,right一定会左移,自动去重
#include <vector>
class Solution {
public:
vector<vector<int> > threeSum(vector<int>& num) {
sort(num.begin(), num.end());
vector<vector<int>>result;
for (int i = 0; i < num.size(); i++) {
if (i > 0 && num[i] == num[i - 1]) continue;
if (num[i] > 0) break;
int left = i + 1;
int right = num.size() - 1;
while (left < right) {
if (num[i] + num[left] + num[right] == 0) {
result.push_back({num[i], num[left], num[right]});
left++;//无论如何这个++不能丢
while (left < right && num[left] == num[left - 1]) {
left++;
}
} else if (num[i] + num[left] + num[right] > 0) {
right--;
} else {
left++;
}
}
}
return result;
}
};
- 四数之和
流程: 1 排序
2 最外层循环(第一个数)
去重
3 中间一层 (第二个数)
去重
4 双指针 left去重
注意事项: target有正有负 不能用num[i] > target 剪枝
计算sum时超出int范围,使用long转换一下
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
vector<vector<int>>result;
for(int i = 0; i<nums.size(); i++){
if(target >= 0 && nums[i] > target) break;
if(target < 0 && nums[i] >= 0) break;
if(i > 0 && nums[i] == nums[i-1]) continue;
for(int j = i+1; j<nums.size(); j++){
if(j > i+1 && nums[j] == nums[j-1]) continue;
int left = j+1;
int right = nums.size()-1;
while(left < right){
long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
if(sum == target){
result.push_back({nums[i], nums[j], nums[left], nums[right]});
left++;
while(left < right && nums[left] == nums[left-1]) left++;
}else if(sum > target) right--;
else left++;
}
}
}
return result;
}
};