DAY7 四数相加II 赎金信 三数之和 四数之和

四数相加II:

好好珍惜一下,这是哈希表专题为数不多能用哈希表做的题目。

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。

例如:

输入:

  • A = [ 1, 2]
  • B = [-2,-1]
  • C = [-1, 2]
  • D = [ 0, 2]

输出:

2

解释:

两个元组如下:

  1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
  2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

对应力扣454题

这题只用输出个数就行,不用输出对应的数字,可以用map来做,基本思路是用map存nums1+nums2的数,用两个for循环遍历nums1+nums2,有重复的就将value+1,表示有n个nums1+nums2等于map中对应的数,之后遍历nums3+nums4,如果nums3+nums4等于-(nums1+nums2)在map中有对应的,计数+n即可。

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
           unordered_map<int,int> map;
           int k=0;
           for(int i=0;i<nums1.size();i++)
           {
               for(int j=0;j<nums2.size();j++)
               {
                   if(map.find(nums1[i]+nums2[j])!=map.end())
                   map.find(nums1[i]+nums2[j])->second++;
                   else
                   map.insert({nums1[i]+nums2[j],1});
               }
           }
               for(int i=0;i<nums3.size();i++)
           {
               for(int j=0;j<nums4.size();j++)
               {
                   if(map.find(0-nums3[i]-nums4[j])!=map.end())
                   k=k+((map.find(0-nums3[i]-nums4[j]))->second);
               }
           }
           return k;
    }
};

赎金信

最简单的一集,对应力扣383题,和242题是一个思路,用数组哈希即可。

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
            int res[26]={0};
            for(int i=0;i<magazine.size();i++)
            {
                res[magazine[i]-'a']++;
            }
             for(int i=0;i<ransomNote.size();i++)
            {
                res[ransomNote[i]-'a']--;
            }
             for(int i=0;i<26;i++)
            {
               if(res[i]<0)return 0;
            }
            return 1;
    }
};

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意: 答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]

这题跟哈希表好像没啥关系,是用双指针来做的,不要看跟四数相加很像,其实完全不一样,对应力扣15题。

注意去重操作,

 if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

这一步很关键。

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

四数之和:

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]

对应力扣18题

这题跟三数之和类似,使用两层for循环+双指针就能解决问题,但是要注意target可能为负数,比如说targer=-5,数组为[-4,-1,0,0],这是满足条件的,所以不能

 if(nums[i]>0)return res;

代码如下:

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

最后两个好像和哈希没啥关系哈,结束!

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值