day 7 三数 四数之和

哈希总结

1. 两数之和

无重,只有一个结果,而不需要顺序执行
查询 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};
    }
};
  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;

    }
};

15. 三数之和

排序 , 然后双指针遍历
因为和为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. 四数之和
    流程: 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; 
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值