需要哈希的地方都能找到map的身影

第454题.四数相加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

思路

本题是使用哈希法的经典题目,而0015.三数之和,0018.四数之和并不合适使用哈希法,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。

而这道题目是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于题目18. 四数之和,题目15.三数之和,还是简单了不少!

如果本题想难度升级:就是给出一个数组(而不是四个数组),在这里找出四个元素相加等于0,答案中不可以包含重复的四元组,大家可以思考一下,后续的文章我也会讲到的。

本题解题步骤:

  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 就可以了

C++代码:

class Solution {
public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {unordered_map<int, int> umap; //key:a+b的数值,value:a+b数值出现的次数// 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中for (int a : A) {for (int b : B) {umap[a + b]++;}}int count = 0; // 统计a+b+c+d = 0 出现的次数// 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。for (int c : C) {for (int d : D) {if (umap.find(0 - (c + d)) != umap.end()) {count += umap[0 - (c + d)];}}}return count;}
};

其他语言版本

Java:

class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {Map<Integer, Integer> map = new HashMap<>();int temp;int res = 0;//统计两个数组中的元素之和,同时统计出现的次数,放入mapfor (int i : nums1) {for (int j : nums2) {temp = i + j;if (map.containsKey(temp)) {map.put(temp, map.get(temp) + 1);} else {map.put(temp, 1);}}}//统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数for (int i : nums3) {for (int j : nums4) {temp = i + j;if (map.containsKey(0 - temp)) {res += map.get(0 - temp);}}}return res;}
}

Python:

class Solution(object):def fourSumCount(self, nums1, nums2, nums3, nums4):# use a dict to store the elements in nums1 and nums2 and their sumhashmap = dict()for n1 in nums1:for n2 in nums2:if n1 + n2 in hashmap:hashmap[n1+n2] += 1else:hashmap[n1+n2] = 1# if the -(a+b) exists in nums3 and nums4, we shall add the countcount = 0for n3 in nums3:for n4 in nums4:key = - n3 - n4if key in hashmap:count += hashmap[key]return count
class Solution:def fourSumCount(self, nums1: list, nums2: list, nums3: list, nums4: list) -> int:from collections import defaultdict # You may use normal dict instead.rec, cnt = defaultdict(lambda : 0), 0# To store the summary of all the possible combinations of nums1 & nums2, together with their frequencies.for i in nums1:for j in nums2:rec[i+j] += 1# To add up the frequencies if the corresponding value occurs in the dictionaryfor i in nums3:for j in nums4:cnt += rec.get(-(i+j), 0) # No matched key, return 0.return cnt

Go:

func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {m := make(map[int]int)   //key:a+b的数值,value:a+b数值出现的次数count := 0// 遍历nums1和nums2数组,统计两个数组元素之和,和出现的次数,放到map中for _, v1 := range nums1 {  for _, v2 := range nums2 {m[v1+v2]++}}// 遍历nums3和nums4数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来for _, v3 := range nums3 {for _, v4 := range nums4 {count += m[-v3-v4]}}return count
}

javaScript:

/*** @param {number[]} nums1* @param {number[]} nums2* @param {number[]} nums3* @param {number[]} nums4* @return {number}*/
var fourSumCount = function(nums1, nums2, nums3, nums4) {const twoSumMap = new Map();let count = 0;// 统计nums1和nums2数组元素之和,和出现的次数,放到map中for(const n1 of nums1) {for(const n2 of nums2) {const sum = n1 + n2;twoSumMap.set(sum, (twoSumMap.get(sum) || 0) + 1)}}// 找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来for(const n3 of nums3) {for(const n4 of nums4) {const sum = n3 + n4;count += (twoSumMap.get(0 - sum) || 0)}}return count;
};

TypeScript:

function fourSumCount(nums1: number[], nums2: number[], nums3: number[], nums4: number[]): number {let helperMap: Map<number, number> = new Map();let resNum: number = 0;let tempVal: number | undefined;for (let i of nums1) {for (let j of nums2) {tempVal = helperMap.get(i + j);helperMap.set(i + j, tempVal ? tempVal + 1 : 1);}}for (let k of nums3) {for (let l of nums4) {tempVal = helperMap.get(0 - (k + l));if (tempVal) {resNum += tempVal;}}}return resNum;
};

PHP:

class Solution {/*** @param Integer[] $nums1* @param Integer[] $nums2* @param Integer[] $nums3* @param Integer[] $nums4* @return Integer*/function fourSumCount($nums1, $nums2, $nums3, $nums4) {$map = [];foreach ($nums1 as $n1) {foreach ($nums2 as $n2) {$temp = $n1 + $n2;$map[$temp] = isset($map[$temp]) ? $map[$temp]+1 : 1;}}$count = 0;foreach ($nums3 as $n3) {foreach ($nums4 as $n4) {$temp = 0 - $n3 - $n4;if (isset($map[$temp])) {$count += $map[$temp];}}}return $count;}
}

Swift:

func fourSumCount(_ nums1: [Int], _ nums2: [Int], _ nums3: [Int], _ nums4: [Int]) -> Int {// ab和: ab和出现次数var countDic = [Int: Int]()for a in nums1 {for b in nums2 {let key = a + bcountDic[key] = countDic[key, default: 0] + 1}}// 通过-(c + d)作为key,去累加ab和出现的次数var result = 0for c in nums3 {for d in nums4 {let key = -(c + d)result += countDic[key, default: 0]}}return result
}

Rust:

use std::collections::HashMap;
impl Solution {pub fn four_sum_count(nums1: Vec<i32>, nums2: Vec<i32>, nums3: Vec<i32>, nums4: Vec<i32>) -> i32 {let mut umap:HashMap<i32, i32> = HashMap::new();for num1 in &nums1 {for num2 in &nums2 {*umap.entry(num1 + num2).or_insert(0) += 1;}}let mut count = 0;for num3 in &nums3 {for num4 in &nums4 {let target:i32 = - (num3 + num4);count += umap.get(&target).unwrap_or(&0);          }}count}
}

Scala:

object Solution {// 导包import scala.collection.mutabledef fourSumCount(nums1: Array[Int], nums2: Array[Int], nums3: Array[Int], nums4: Array[Int]): Int = {// 定义一个HashMap,key存储值,value存储该值出现的次数val map = new mutable.HashMap[Int, Int]()// 遍历前两个数组,把他们所有可能的情况都记录到mapfor (i <- nums1.indices) {for (j <- nums2.indices) {val tmp = nums1(i) + nums2(j)// 如果包含该值,则对他的key加1,不包含则添加进去if (map.contains(tmp)) {map.put(tmp, map.get(tmp).get + 1)} else {map.put(tmp, 1)}}}var res = 0 // 结果变量// 遍历后两个数组for (i <- nums3.indices) {for (j <- nums4.indices) {val tmp = -(nums3(i) + nums4(j))// 如果map中存在该值,结果就+=valueif (map.contains(tmp)) {res += map.get(tmp).get}}}// 返回最终结果,可以省略关键字returnres}
}

C#:

public int FourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {Dictionary<int, int> dic = new Dictionary<int, int>();foreach(var i in nums1){foreach(var j in nums2){int sum = i + j;if(dic.ContainsKey(sum)){dic[sum]++;}else{dic.Add(sum, 1);}}}int res = 0;foreach(var a in nums3){foreach(var b in nums4){int sum = a+b;if(dic.TryGetValue(-sum, out var result)){res += result;}}}return res;}

算法刷题-哈希表-四数相加相关推荐

  1. LeetCode刷题——哈希表(python语言)

    LeetCode刷题--哈希表(python语言) 一.哈希表 1.1 哈希表的概念 哈希表,也叫散列表.其实可以很像python的字典,也就是键(key)值(Hash(key))对,最简单也最常用的 ...

  2. C#LeetCode刷题-哈希表

    哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串   24.2% 中等 18 四数之和   ...

  3. 代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

    今日学习的文章和视频链接 454文章链接: link 454视频讲解链接: link 383文章链接: link 383视频暂无讲解 15文章链接: link 15视频讲解链接: link 18文章链 ...

  4. 代码随想录算法训练营第七天 | 454.四数相加II ,383. 赎金信 ,15. 三数之和,18. 四数之和

    一.参考资料 四数相加II 题目链接/文章讲解/视频讲解:https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II. ...

  5. 代码随想录算法训练营第6天 | 454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

    一.Leetcode 454. 四数相加 II 相当于两数相加.但是呢很巧妙的是,卡哥在遍历CD数组时把查哈希表的方法融入了进去.学习一下. 二.Leetcode 383. 赎金信 更简单了,主要是审 ...

  6. 代码随想录算法训练营15期 Day7 | 454.四数相加II、 383. 赎金信 、15. 三数之和、18. 四数之和

    目录 力扣 454.四数相加II 题解:哈希表-map-unordered_map 力扣 383.赎金信 题解1:暴力解法 题解2:哈希表--数组 力扣 454.四数相加II 题目: 给你四个整数数组 ...

  7. 代码随想录算法训练营第7天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和

    454.四数相加II 力扣题目链接 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i]+B[j]+C[k]+D[l] = 0. 为了 ...

  8. 代码随想录算法训练营第七天| 454.四数相加II 、383. 赎金信、15. 三数之和、18. 四数之和

    454. 四数相加 II 题目: 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= ...

  9. 代码随想录算法训练营第七天 | 454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和

    454. 四数相加 II 题解及想法 通过两个for循环先遍历a和b,key放a和b两数之和,value 放a和b两数之和出现的次数,再通过两个for循环遍历c和d,如果0-(c+d) 在map中出现 ...

最新文章

  1. Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战
  2. 第三组 通信一班 030 ISISv6
  3. KuYun企业授权管理系统源码开源版
  4. one-hot encoding 并非分类变量编码的唯一选择
  5. PHP利用Mysql锁解决高并发
  6. 学python电脑要装什么_初学 Python 需要安装哪些软件?
  7. AD下安装Exchange及简单收发邮件【视频】
  8. 考试一个程序员,1f=0.1
  9. sonar jacoco 覆盖率为0_接口测试代码覆盖率(jacoco)方案分享
  10. ENVI5.3安装中国国产卫星支持工具
  11. ibm刀箱服务器型号查询,IBM 服务器模块 刀箱模块
  12. android 支付宝手势密码锁,Android仿支付宝手势密码解锁
  13. 使用导入 Excel 的方式批量修改文件名称及文件扩展名
  14. 【C++】C++中头文件使用双引号与书名号的区别
  15. 如何将一个vector内容赋值给另一个vector C/C++
  16. 英语四级XYZ字母开头单词+托福高频单词
  17. 129、易燃气体的分级
  18. QT起一个线程实时监测某个进程是否正常运行
  19. 购买重疾险的十大误区(建议收藏)
  20. Centos RPM安装包制作

热门文章

  1. 输入一个总秒数,计算几小时零几分钟零几秒钟。
  2. Edge浏览器实现免费数学公式识别LaTex、Mathtype、Word、Markdown等亲测可用,不限次数
  3. 微信小程序开发的作用_分享微信小程序开发可以实现什么
  4. 修改老commit的message信息
  5. VB.NET小报表(收据)打印
  6. script 标签 async 属性
  7. 一文读懂transformer
  8. 2021山东计算机专业单招院校,2021年山东单招学校有哪些 高职单招院校名单及排名...
  9. win32操作Excel 保存文件
  10. 尽管颓废了一年,但我仍未放弃梦想「2021年终总结」