【哈希表】哈希表应用之四数相加

题目:给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

分析:nums1[i]  + nums2[j] + nums3[k] +nums4[l] == 0 ,则nums1[i] + nums2[j] = -(nums3[k] + nums4[l]),所以我们可以设置一个哈希表存放 -(nums3[k] + nums4[l])的值,然后用双层循环遍历nums1和nums2,寻找他们的和等于 -(nums3[k] + nums4[l])的个数。

哈希结构可以使用数组或者unordered_set、unordered_map,首先排除数组,因为nums1等数组的元素大小范围太大,不适合用数组。因为我们不需要返回索引,所以可以尝试用unordered_set实现。

一、unordered_set具体代码实现

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

但是这样的代码对于如果有多组[k,l]与[i,j]对应的情况会只计算一种,所以需要修改代码,但是目前本人没有仔细思考怎么样修改才能正确实现功能,欢迎大家评论留言讨论。

运行结果如下所示:

二、unordered_map具体代码实现

unordered_map可以简单解决unordered_set存在的问题,它可以记录同样的-(nums3[k] + nums4[l])值出现的次数,因此不会漏计。

class Solution {
public:
   int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
      int result = 0;
      unordered_map<int, int> hash;
      for(int k = 0; k < nums3.size(); k++) {
         for(int l = 0; l < nums4.size(); l++) {
           hash[-(nums3[k] + nums4[l])]++;
         } 
      }
      for(int i = 0; i < nums1.size(); i++) {
         for(int j = 0; j < nums2.size(); j++) {
           if(hash[nums1[i] + nums2[j]] != 0) {
              result += hash[nums1[i] + nums2[j]];
           }
         }
      }
      return result;
    }
};

运行结果如下所示:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值