数和的合集

        454 是找四个数相加等于零的情况,我瞎了

        a+b+c+d=0   先算a+b  key是a+b、value是a+b出现的次数,然后找-(c+d)就OK了

本题解题步骤:

  1. 首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。

  2. 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。

  3. 定义int变量count,用来统计a+b+c+d = 0 出现的次数。

  4. 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。

  5. 最后返回统计值 count 就可以了

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int>map1;
        for(auto&a:nums1){
            for(auto &b:nums2){
                map1[a+b]++;
            }
        }
        int count=0;
        for(auto&c:nums3){
            for(auto &d:nums4){
                if(map1.find(-(c+d))!=map1.end())
                    count+=map1[-(c+d)];
            }
        }
        return count;
    }
};

一个函数秒杀 2Sum 3Sum 4Sum 问题 ---------lubuladong

三数之和其实就是两数之和的进化版

15三数之和

思路排序+双指针

首先1.处理size小于3

class Solution {
        vector<vector<int>>TwoSum(vector<int>&nums,int start,int target){
        vector<vector<int>>vec;
        int len=nums.size();
        int left=start,right=len-1;
        while(left<right){
            int sum=nums[left]+nums[right];
            if(sum==target){
                    vec.push_back({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(sum>target)
                 while(left<right&&nums[right]==nums[--right]);
             else
                while(left<right&&nums[left]==nums[++left]);
        }
        return vec;
    }
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>>vec;
        if(nums.size()<3)return vec;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n-2;i++){
            if(nums[i]>0)return vec;
            if(i>0&&nums[i]==nums[i-1])continue;
            int target=0-nums[i];
            vector<vector<int>>tupless=TwoSum(nums,i+1,target);
            if(!tupless.empty()){
                for(auto &tmp:tupless){
                    tmp.push_back(nums[i]);
                    vec.push_back(tmp);
                }
            }
        }
        return vec;
    }
};

 

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>>vec;
        if(nums.size()<3)return vec;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n-2;i++){
            if(nums[i]>0)return vec;
            if(i>0&&nums[i]==nums[i-1])continue;
            int left=i+1,right=n-1;
            while(left<right){
                int sum=nums[i]+nums[left]+nums[right];
                if(sum==0){
                    vec.push_back({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(sum>0)
                    while(left<right&&nums[right]==nums[--right]);
                else
                    while(left<right&&nums[left]==nums[++left]);
            }  
        } 
        return vec;
    }
};

时间复杂度:

        因此枚举的总时间复杂度为 O(N^2)O(N^2)。由于排序的时间复杂度为 O(N log N)O(NlogN),在渐进意义下小于前者,因此算法的总时间复杂度为 O(N^2)O(N^2)。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/3sum/solution/san-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

        空间复杂度主要是排序nlogn,也可以看作O(n)

18 四数之和

         这里由于不是零了,所以也就不存在当一个数大于target就返回的那种

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>>vec;
        if(nums.size()<4)return vec;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n-3;i++){
        //    if(nums[i]>target)return vec;
            if(i>0&&nums[i]==nums[i-1])continue;
            for(int j=i+1;j<n-2;j++){
           //     int tmp=target-nums[i];
          //      if(nums[j]>tmp)break;
                if(j>i+1&&nums[j]==nums[j-1])continue;
                int left=j+1,right=n-1;
                while(left<right){
                    if(nums[i]+nums[j]==target-nums[left]-nums[right]){
                        vec.push_back({nums[i],nums[j],nums[left],nums[right]});
                    while(left<right&&nums[left]==nums[left+1])left++;
                    while(left<right&&nums[right]==nums[right-1])right--;
                    right--;left++;
                    }else if(nums[i]+nums[j]>target-nums[left]-nums[right])
                        while(left<right&&nums[right]==nums[--right]);
                    else
                        while(left<right&&nums[left]==nums[++left]);
                }
            }
        }
        return vec;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值