第六天 第三章 哈希表part02 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

454.四数相加II 

刚开始想到用两个数组去分别储存其中两个数组的和,然后再将得到的两个数组求和为0时,定义一个res来存储四数之和为0的个数。但行不通,问题我也不知道在哪里。后来用哈希表去解决。将两个数组相加并存入到哈希表中,再将0减去另外两个数组的和,再哈希表中查找最终的结果。key值用来存放数值,value用来存放数值出现的个数。

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
    unordered_map<int,int> map;
    int res=0;
    for(int i=0;i<nums1.size();i++){
         for(int j=0;j<nums2.size();j++){
            map[nums1[i]+nums2[j]]++;
    }
    }
     for(int i=0;i<nums3.size();i++){
         for(int j=0;j<nums4.size();j++){
         int target=0-(nums3[i]+nums4[j]);
         res+=map[target];
    }
    }  
    return res;
    }
};

383. 赎金信

想到用map,但是数组更简单

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
    unordered_map<char,int> map1;
    unordered_map<char,int> map2;
    for(int i=0;i<ransomNote.size();i++){
        char c = ransomNote[i];
        map1[c]++;
    }
    for(int i=0;i<magazine.size();i++){
        char c = magazine[i];
        map2[c]++;
    }
    for (int i = 0; i < ransomNote.size(); i++) {
            char c = ransomNote[i];
            if (map1[c] > map2[c]) {
                return false;
            }
        }
    return true;
    }
};

15. 三数之和

刚开始想用哈希表做,但是做了回好像没思路。突然想到前面类似的题,排序后使用双指针。其中的细节部分:

1.循环的条件。while(left<right&&nums[right-1]==nums[right])顺序不能反。

2.如何处理相邻数值是相等的问题。

细节挺多的,需要反复练习。

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;
        int right=nums.size()-1;
        while(left<right){
        if(nums[i]+nums[left]+nums[right]==0)
         {
        res.push_back({nums[i],nums[left],nums[right]});
        while(left<right&&nums[left+1]==nums[left]) left++;
        while(left<right&&nums[right-1]==nums[right]) right--;
         left++;
         right--;
        }
        
        else if(nums[i]+nums[left]+nums[right]>0) {
          right--;   
        }
        else{
            left++;
        }
    }
    }
        return res;
    }
};

 18. 四数之和

有了三数之和后,四数之和采用相同的办法也可以解决。

其中要注意的问题:

1.剪枝问题。if(nums[i]>target&&nums[i]>=0){ break;}  这里和三数之和不一样,不确定target的值。所以不能用nums[i]>0去判断。

2.有些案例数组数值大,导致相加后数值越界加一个(long)去处理。

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&&nums[i]>=0){
         break;   
        }
        if(i>0&&nums[i]==nums[i-1]){
        continue;
        }
        for(int next=i+1;next<nums.size();next++){
            if(nums[i] + nums[next] > target && nums[i] + nums[next] >= 0){
         break;   
        }
        if(next>i+1&&nums[next]==nums[next-1])  continue;
        int left=next+1;
        int right=nums.size()-1;
        while(left<right){
        if((long)nums[i]+nums[next]+nums[left]+nums[right]==target)
         {
        res.push_back({nums[i],nums[next],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((long)nums[i]+nums[next]+nums[left]+nums[right]>target) {
          right--;   
        }
        else{
          left++;
        }
        }
        }
    }
        return res;
    }
}; 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值