数据结构算法-哈希表:四数相加II

代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和 本文总结了算法训练营第六天的学习内容,包括四道哈希表相关题目解法。454.四数相加II通过分组+哈希表将O(n^4)优化为O(n²);383.赎金信使用数组哈希统计字符频率;15.三数之和采用排序+双指针法,重点处理去重逻辑;18.四数之和在双指针基础上增加一层循环。核心思想是利用哈希表优化查找效率,通过排序+双指针处理多数和问题,同时注意各类边界条件和去重处理。 阅读详情

1.1 、问题描述:四数相加II

力扣题目链接https://leetcode.cn/problems/4sum-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

解释:

两个元组如下:

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

    1.2、思路:

    核心思想:分组+哈希表

    用哈希表(如 Java 中的 HashMap)存储第一组的两数和,key 为 某一次sum的具体值,value 为该和出现的次数。

    分组处理:将四个数组分为两组(A和B为一组,C和D为另一组)。

    1. 预处理第一组:遍历 A 和 B 的所有元素组合,计算每对元素的和(a + b),并以该和为键,出现次数为值,存入哈希表中。例如,使用 map.getOrDefault(sum, 0) 来统计次数(Java)
    2. 处理第二组:遍历 C 和 D 的所有元素组合,计算每对元素的和(c + d),并检查哈希表中是否存在键 -(c + d)(即 0 - (c + d))。若存在,则将对应的值(即出现次数)累加到结果中。
    3. 返回结果:累计的次数即为满足条件的元组数量。

    这就是哈希表的 “空间换时间” 特性

    1.3 、指针数组示意图:

    可以看到 A+B的sum值会作为key ,而的 A+B可能会有多个相同的值,即使用value存储。如:

    A+B的-1 出现两次对应 就是 -1 作为key  2作为value

    第一轮结果 :C+D和 A+B的值校验的结果,如果存在符合条件的。即key=tar=-(C+D)。value就是出现的次数 。

    1.4、代码实现 

    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 解决LeetCode 454.四数相加II问题
     * 题目:给定4个整数数组nums1、nums2、nums3、nums4,计算有多少个元组(a,b,c,d)
     * 使得a∈nums1, b∈nums2, c∈nums3, d∈nums4 且 a+b+c+d=0
     */
    public class FourSumCount {
    
        /**
         * 核心方法:计算满足条件的四元组数量
         * @param nums1 第一个整数数组
         * @param nums2 第二个整数数组
         * @param nums3 第三个整数数组
         * @param nums4 第四个整数数组
         * @return 满足a+b+c+d=0的四元组总数
         */
        public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
            // 1. 创建哈希表存储"两数和"与"出现次数"的映射
            // 为什么用哈希表?因为要快速查询"某个和是否存在"以及"存在多少次",时间复杂度O(1)
            // key: nums1和nums2中任意两数的和(a+b)
            // value: 这个和出现的次数(即有多少对(a,b)能算出这个和)
            Map<Integer, Integer> sumMap = new HashMap<>();
    
            // 2. 遍历nums1和nums2,计算所有可能的a+b,并统计次数存入哈希表
            // 为什么遍历这两个数组?因为要把四数相加拆成两组(a+b)和(c+d),降低复杂度
            // 外层循环:取出nums1中的每个元素a
            for (int a : nums1) {
                // 内层循环:取出nums2中的每个元素b
                for (int b : nums2) {
                    // 计算当前a和b的和
                    int sumAB = a + b;
    
                    // 把sumAB存入哈希表,并更新出现次数
                    // getOrDefault(sumAB, 0):如果sumAB已存在,取它的次数;否则取默认值0
                    // +1:表示当前(a,b)组合又贡献了一次这个和
                    sumMap.put(sumAB, sumMap.getOrDefault(sumAB, 0) + 1);
                }
            }
    
            // 3. 初始化结果变量,用于累计满足条件的四元组数量
            int result = 0;
    
            // 4. 遍历nums3和nums4,计算所有可能的c+d,寻找能凑成0的组合
            // 为什么遍历这两个数组?因为目标是a+b + c+d = 0 → 即a+b = -(c+d)
            // 外层循环:取出nums3中的每个元素c
            for (int c : nums3) {
                // 内层循环:取出nums4中的每个元素d
                for (int d : nums4) {
                    // 计算当前c和d的和
                    int sumCD = c + d;
    
                    // 计算需要的目标和:能与sumCD凑成0的a+b应该是 -sumCD
                    int targetSumAB = -sumCD;
    
                    // 从哈希表中查询targetSumAB的出现次数
                    // 如果存在,说明有这么多对(a,b)能与当前(c,d)组成满足条件的四元组
                    // 把这个次数加到结果中
                    result += sumMap.getOrDefault(targetSumAB, 0);
                }
            }
    
            // 5. 返回最终统计的四元组总数
            return result;
        }
    
        // 测试代码:用具体例子验证逻辑
        public static void main(String[] args) {
            FourSumCount solution = new FourSumCount();
            
            // 测试用例:4个简单数组
            int[] nums1 = {1, 2};
            int[] nums2 = {-1, 3};
            int[] nums3 = {-2, 4};
            int[] nums4 = {0, -3};
            
            // 调用方法计算结果
            int count = solution.fourSumCount(nums1, nums2, nums3, nums4);
            
            // 预期结果:1(对应四元组(2,3,-2,-3),因为2+3+(-2)+(-3)=0)
            System.out.println("满足条件的四元组数量:" + count); // 输出:1
        }
    }

    个人总结学习用,对部分内容进行了简单的处理和归纳,如有谬误,希望大家指出,
    持续修订更新中。

    参考文档:

    1. 程序员 Carl. 代码随想录(LeetCode 数据结构与算法刷题攻略)(EB/OL). https://www.programmercarl.com/,2025-02/2025-10.
    2. 《数据结构》课程教学大纲(2024 版)(EB/OL). https://m.book118.com/html/2024/0423/8110022111006061.shtm,2024-04/2025-10.
    3. 《数据结构》课程教学大纲(软件工程专业)(EB/OL). https://m.renrendoc.com/paper/329728026.html,2024-05/2025-10.
    4. 程序员 Carl. LeetCode-Master(代码随想录刷题攻略 GitHub 仓库)(EB/OL). https://github.com/youngyangyang04/leetcode-master,2025-09/2025-10.

    逆向实战:Soul聊天协议加密与Frida绕过检测技术解析 本文详细解析了Soul聊天协议的逆向工程实战,重点介绍了使用Frida绕过检测技术的具体方法。通过IDA和JADX进行静态分析,结合Frida动态调试,揭示了数据加密与解密的核心逻辑,并提供了完整的逆向工作流和实用技巧,帮助开发者深入理解协议逆向过程。 阅读详情

    相关推荐

    LabVIEW调用.so文件的方法

    LabVIEW调用.so文件的方法

    m0_37878912的博客 3025

    【数据结构与算法】哈希表2:四数相加II & 赎金信 & 三数之和 & 四数之和

    分析题意,题目中是四个独立数组,要求我们只要找到nums1[i] + nums2[j] + nums3[k] + nums4[l] = 0,同时这四个数组长度相同,并且在本题目中并没有限制数组元素出现的次数,也就是说只要满足四数组元素相加为0都可以作为一组解。使用哈希解法的话,前面的学习我们也已经知道,数组也是一种简单的哈希表,通过定义一个record[26]的数组(因为条件说明仅为小写字母),首先遍历所有magazine中的元素对应record数组中的索引,出现相同的key值就将该value加一。

    以放的博客 783

    【探秘】二维异形件重叠移除算法:从度量到消除的实战解析

    本文深入解析二维异形件重叠移除算法的核心技术与实战应用,涵盖重叠度量、零件扰动策略及消除方法。通过NFP(临界多边形)技术、空间分区加速等优化手段,有效解决异形件排版中的重叠问题,提升材料利用率和计算效率。适合制造业、CAD软件开发者及算法工程师参考。

    weixin_28698059的博客 253

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

    把前两个数组的和放到哈希表中,然后再两个for循环进行一个哈希表的匹配,时间复杂度是O(n^2)思路:利用hashmap的额外空间来代替第三层的for循环,从而将时间复杂度减少到O(n^2)解决方案:对nums进行排序,然后在第一和第二次循环过程中维护一个。变量,用于存储之前已经遍历过的情况,防止结果的重复。简单题,存内容到hashmap里面然后去判断即可。

    ylxget的博客 408

    CATIA_DELMIA_V5R2019安装包下载及安装教程破解

    CATIA_V5R2019/DELMIA_V5R2019安装包下载及安装教程破解

    一只机械工装熊的博客 8387

    半导体设备上位机开发:我的经验与新人指导

    半导体设备上位机开发是一项复杂而富有挑战性的工作,需要扎实的技术基础和丰富的经验。如果你对半导体设备上位机开发感兴趣,欢迎随时与我交流,我会尽力帮助你!

    qq_43518667的博客 2734

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

    主要使用双指针,解决哈希表章节的算法题目。

    qq_57465625的博客 473

    用Python进行GEO数据挖掘(学习笔记四):富集分析

    该笔记详细解释了富集分析的工作原理,并简要地利用gseapy在python中进行富集分析的操作。

    m0_64111502的博客 5649

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

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

    weixin_46108098的博客 315

    分析android逆向的学习路线

    俗话说:“一入逆向深似海,从此头发是路人”。 安卓逆向作为当下热门行业“网络安全”的主要技术之一,已经受到了越来越多人的青睐。但是很多刚入门的新手小伙伴对于怎么去学习却还很是迷糊。本文就分享一下android逆向的学习路线供大家参考。 目前学习安卓逆向的人群大约分为两种: 第一种是完全没有任何基础的计算机纯小白; 第二种是本来就做开发懂编程的IT行业人员。 我们就针对这两个不同的人群做一下安卓逆向的学习路线分析。 一、无基础小白想入门 作为没有任何基础想要入门的计算机纯小白,学习上推荐参照以下步骤: (一

    Hacker_by_V的博客 3078

    金融风控实战:用Python从零搭建贷款违约预测模型(附完整数据集)

    本文详细介绍了如何使用Python从零构建金融风控中的贷款违约预测模型,涵盖数据清洗、特征工程、模型构建与评估等全流程。通过实战案例展示逻辑回归、XGBoost和LightGBM三大算法的对比,特别强调AUC-ROC指标在金融风控中的重要性,并附完整数据集和代码实现。

    weixin_29175469的博客 240

    代码随想录一刷记录Day6——leetcode454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

    本文总结了几道LeetCode哈希表和双指针相关的算法题解。454题使用哈希表统计四数相加为0的组合数;383题通过数组哈希判断字符串包含关系;15题采用双指针法解决三数之和问题,并处理去重;18题在15题基础上扩展为四数之和。每道题都详细分析了思路,并提供了C++代码实现,重点讲解了哈希表的使用技巧和双指针的去重方法。

    wjw0318的博客 572

    mjlab & MimicKit 宇树 G1 人形机器人强化学习训练部署

    基于mjlab框架训练Unitree G1人形机器人执行双旋踢的示例。参考动作源自Jason Peng的MimicKit项目。数据转换脚本(MimicKit pkl → mjlab csv)完整训练结果与超参数预训练ONNX检查点用于部署实体硬件部署指南⚠️ 免责声明仅用于教育目的。对于因尝试复现此处展示结果而导致的财产损失或人身伤害,我们概不负责。操作硬件时请谨慎行事并保持良好判断力。

    2506_90492529的博客 1700

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

    剪枝的细节不同,三数相加,只需要判断第一个数是否大于0即可,因为排序完了之后如果第一个数都大于0了,那么target=0的话一定是做不到的,但是四数相加,如果第一个数大于target值,但是target是负数的话,第一个数加第二个数是有概率等于target值的。对于第一个数,判断是否大于0,来决定是否剪枝,因为第一个数就大于0的话,那么这三个数一定不能等于0。这两个指针的去重操作,也是后指针如果等于前面一个数,就指针前移,前指针如果等于后一个数,指针后移。与三数相加类似,但有许多细节不同。

    weixin_63312229的博客 368

    复分析 阿尔福斯(Ahlfors) 第三版答案 英文

    答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

    Statistics and Machine Learning Toolbox

    Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

    代码随想录 | Day7

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档。

    优快云_0853的博客 447

    ET2012新版免狗免安装绿色软件

    ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

    day7刷题

    454.四数相加II。

    weixin_43481934的博客 141

    精雕软件(JDpaint) 5.5 绿色版

    精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

    LeetCode:454. 四数相加 II —— 哈希表为什么叫哈希表~

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

    Super algorithm 的博客,技术爱好者。 908

    力扣16:四数相加

    本题给的四个数组的元素不是连续的,并且元素个数和大小不确定,所以不能选数组,又因为需要记录元素出现的次数,元素和的值相同但是不是同一种排列组合也需要记录,不需要去重,所有不能用set,综上只能用map。本题目是把四个数组分成两大份,第一份是俩数组,进行遍历,计算元素之和以及出现的次数,记录在哈希表中,第二份的俩数组,计算元素和,并用target减去元素和,在第一份的哈希表中查找该值,并记录次数。为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500。

    qq_53340107的博客 1678

    【代码随想录 | Leetcode | 第九天】哈希表 | 快乐数 | 四数相加 II | 赎金信

    【代码随想录 | Leetcode | 第九天】哈希表 | 快乐数 | 四数相加 II | 赎金信

    热爱编程的小K的博客 2124

    代码随想录算法训练营第十天|1. 两数之和,第454题.四数相加II

    在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。但是,数组中同一个元素不能使用两遍。

    lcy57__的博客 2279

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

    数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。这时候就可以用到字典了。

    懒羊羊在努力的博客 2314

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

    哈希法、C语言、数组结构、四数相加、三数之和、四数之和

    leehal的博客 924

    Java实现 LeetCode 454 四数相加 II

    454. 四数相加 II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l...

    5405

    代码随想录算法训练营第七天 | 哈希表理论基础 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

    这道题我个人直观感觉是的拓展,但搞得我不知道该构建哈希表来find什么(比如说我遍历到数组1的元素a,我不知道在下一个数组构成的hash表来find什么元素)。然后就去看参考视频了。卡哥的视频解答了我的疑惑我们可以让前两个数组相加划为一块,后两个元素相加划为一块。但也有可能会产生另一个问题。因为当我们构建一块的过程中是要遍历相加的,这种方法的时间复杂度是O(),而两两划分的时间复杂度是O(进而衍生到如果出现“六数相加”、“八数相加”的题目,为了算法时间复杂度,在选用哈希数据结构的时候,也会陷入纠结。

    C_J314的博客 757

    代码随想录算法训练营第六天:四数相加II,赎金信,三数之和,四数之和,哈希表完结

    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 。例如:输入:输出:2解释:两个元组如下:思路:本题相较于昨天写的两数之和,改成了四个独立的数组,但是

    guoba250的博客 1189

    数据结构与算法学习day10-哈希表-快乐数、两数之和、四数相加 II

    对于 A 和 B,我们使用二重循环对它们进行遍历,得到所有 A[i]+B[j] 的值并存入哈希映射中。对于哈希映射中的每个键值对,每个键表示一种 A[i]+B[j],对应的值为 A[i]+B[j] 出现的次数。那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。当遍历到 C[k]+D[l] 时,如果 −(C[k]+D[l]) 出现在哈希映射中,那么将 −(C[k]+D[l]) 对应的值累加进答案中。用对应的value值、插入值。

    weixin_48990728的博客 1151
    上一篇: 数据结构算法-哈希表:两数之和
    下一篇: 数据结构算法:哈希表-赎金信
    SoulmateShkart
    博客等级 码龄4年 5粉丝 22原创
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    个

    红包个数最小为10个

    元

    红包金额最低5元

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

    抵扣说明:

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

    余额充值