四数相加II

力扣题目链接(opens new window)

给定四个包含整数的数组列表 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

初见分析

题目给我们提供了nums1~4四个长度相同输入数组,我们需要在每个数组中选择一个下标,组成一个含4个元素的元组

这四个下标对应的数组中的元素相加需要正好为0

似乎没有能够使用哈希表的点

存下标吗?下标元组按题意来算有n的四次方种

也不太可能用暴力法,那样需要四个循环,复杂度为n的四次方

思路

先声明,本题就是哈希法的经典题型。如何想到用哈希表是本题的关键。先梳理思路吧

由题意,我们需要在四个数组中找出相加等于零的情况出现的次数

注意,不需要给出对应的元素,只要记录等于零这种情况出现的次数

一种自然的想法是:

int count = 0;
for(a:A){
for(b:B){
for(c:C){
for(d:D){
int sum = a + b + c + d;
if(sum ==0){
count ++;
}
}
}
}
}

时间复杂度n * n * n * n,不太行

反正肯定是要遍历数组的,能不能分开遍历?

于是,可以将AB分为一组,CD分为另一组

而且,肯定不能同时遍历这两组,要不然还是n * n * n * n

所以得分开计算遍历到的值的和

题目的要求是

nums1[i]+nums2[i]+nums3[i]+nums4[i] = 0

设A遍历到的值为a,以此类推有b、c、d

那么:

a+b+c+d = 0

先遍历AB数组,计算a+b,存入一个集合

这里有一种情况需要注意:

例如所给的数组中元素全为0,那么不同的0相加也算是不同的一种情况

所以计算a+b时还要记录其出现过的次数

因为需要记录两个值,所以使用map比较合适

然后遍历CD数组,计算c+d

那么这里就有使用哈希表的地方了,参考两数之和的处理方式

我们可以去集合中查询一个 target ,target = 0-(c+d)

如果 target 在集合中存在,那么就找到了一个满足条件的情况

不难看出,这里的target就是a+b的值

代码

class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> map;//创建一个map作为哈希表
//遍历前两个数组A、B
for(int n1 : nums1){//也可以写auto
for(int n2 : nums2){
// int sum = n1 + n2;
map[n1 + n2]++;//在map中的sum位置标记1
}
} int count = 0;
//遍历剩下的数组CD
for(int n3 : nums3){
for(int n4 : nums4){
int sum = n3 + n4;
int target = 0 - sum;
auto iter = map.find(target);
if(iter != map.end()){//找到target
count += map[target];
}
}
}
return count;
}
};
注意点
1、遍历vector

可以使用c++中迭代器的风格去遍历,即:

for(int n1 : nums1){//也可以写auto,让编译器自己去判断类型,当然题目已经给了vector的类型就直接写int
for(int n2 : nums2){
// int sum = n1 + n2;
map[n1 + n2]++;//在map中的sum位置标记1
}
}

也可以传统一点(实际上这样也是用迭代器)

for (it = nums1.begin(); it != nums1.end();it++) {
cout << *it << " ";
}
2、map插入数据
#include <map>

void printMap(map<int,int>&m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key = " << it->first << " value = " << it->second << endl;
}
cout << endl;
} void test01()
{
//插入
map<int, int> m;
//第一种插入方式
m.insert(pair<int, int>(1, 10));
//第二种插入方式
m.insert(make_pair(2, 20));
//第三种插入方式
m.insert(map<int, int>::value_type(3, 30));
//第四种插入方式
m[4] = 40;
printMap(m); //删除
m.erase(m.begin());
printMap(m); m.erase(3);
printMap(m); //清空
m.erase(m.begin(),m.end());
m.clear();
printMap(m);
} int main() { test01(); system("pause");
return 0;
}

就用第四中就行,把map当成python中的字典

【LeetCode哈希表#5】四数相加II(map)的更多相关文章

  1. 【哈希表】leetcode454——四数相加II

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

  2. 代码随想录算法训练营day07 | leetcode 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

    LeetCode 454.四数相加II 分析1.0 这个最直接暴力法,不过过于暴力了,害怕.jpg 失误 读题理解失误:题目要求的是四元组的个数,读完题到我这里成了输出四元组,悲哉 分析2.0 记录有 ...

  3. Leetcode 454.四数相加II

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

  4. Java实现 LeetCode 454 四数相加 II

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

  5. 代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和

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

  6. 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和

    [算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...

  7. 四数相加II & 赎金信 & 三数之和 & 四数之和

    一.四数相加Ⅱ 454. 四数相加 II 1.方法概述 首先定义一个map,key放a和b两数之和,value 放a和b两数之和出现的次数.遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到 ...

  8. LeetCode 454.四数相加 II(C++)

    给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...

  9. LeetCode454. 四数相加 II

    题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...

  10. [Swift]LeetCode454. 四数相加 II | 4Sum II

    Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l)there are such th ...

随机推荐

  1. 混沌测试平台 Chaos Mesh

    混沌测试平台 Chaos Mesh Chaos Mesh 是PingCap团队研发的一款用于测试kubernetes环境的工具.通过人为地在集群中注入故障来检测集群对故障的处理以及恢复能力.更详细信息 ...

  2. 小记录 单选框的注意点 html中字符串拼接 el-upload手动上传 表格跳转 v-for动态添加背景色 控制label标签于文本框之间的间距

    在element-ui中 单选框的v-model的值最好是一个字符串 否者可能不能够进行数据回填哈 单选框 的类型必须是字符串类型哈 在elemnet-ui中 如果你想从A页面拿到B页面中的值 可以有 ...

  3. 设计模式-2 简单工厂模式Factory Method

    设计模式-2 简单工厂模式 1 意图: 定义一个用户创建对象的接口,让子类决定实例化那个类.Factory Method使一个类的实例化延迟到其子类 使用场景:将一个类的实例化延迟到其子类结构: 优缺 ...

  4. Spring自带的这11个工具类,真香!

    前言 最近有些小伙伴,希望我分享一些好用的工具类,帮他们提升开发效率. 今天这篇文章专门跟大家一起总结一下,Spring框架本身自带的一些好用的工具类,希望对你会有所帮助. 1 Assert 很多时候 ...

  5. P7907 [Ynoi2005] rmscne题解

    题目链接:rmscne 神仙经典数据结构难题.看到求区间种类数有关的东西,需要下意识的反应到经典老题 HH的项链,这里可以学习我这篇 题解.具体学习下扫描线怎么做这类东西的. 看看本题,首先处理区间查 ...

  6. Arduino语言基础(萌新)

    Arduino语言基础(萌新) Arduino语言注解Arduino语言是建立在C/C++基础上的,其实也就是基础的C语言,Arduino语言只不过把AVR单片机(微控制器)相关的一些参数设置都函数化 ...

  7. 从TF-IDF 到BM25, BM25+,一文彻底理解文本相关度

    相关性描述的是⼀个⽂档和查询语句匹配的程度.我们从搜索引擎召回时,肯定希望召回相关性高的数据,那么如何来量化相关度呢. 首先,我们定义,一个文档doc,由多个词语 term 组成. 最早,通过最简单的 ...

  8. 教你用JavaScript实现表情评级

    案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript编程实战案例,做一个表情评价程序.用户打星进行评价,表情会根据具体星星数量发生变化. 案例演示 点击星星 ...

  9. Java21 + SpringBoot3集成七牛云对象存储OSS,实现文件上传

    目录 前言 实现步骤 引入maven依赖 修改配置文件 创建七牛云配置类 创建文件操作服务类 创建文件操作控制器 前端实现 运行效果 总结 前言 近日心血来潮想做一个开源项目,目标是做一款可以适配多端 ...

  10. 使用VNC在Windows上远程访问Ubuntu服务器

    Step 0:事前准备 一台安装了ghome桌面的Ubuntu服务器(用作server) 一台Windows机器(用作client) Step 1:Linux服务器 在Ubuntu上安装一个VNC服务 ...