【哈希表】leetcode454.四数相加II(C/C++/Java/Python/Js)

news2024/11/24 16:51:57

leetcode454.四数相加II

  • 1 题目
  • 2 思路
  • 3 代码
    • 3.1 C++版本
    • 3.2 C版本
    • 3.3 Java版本
    • 3.4 Python版本
    • 3.5 JavaScript版本
  • 4 总结


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

1 题目

题源链接
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

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

在这里插入图片描述


2 思路

暴力想法是:四个for循环循环四个数组分别相加,显然时间复杂度是O(n4)。

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

本题解题步骤:

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

是不是很妙!!!
如果还没有get到可以看Carl哥的视频讲解


3 代码

3.1 C++版本

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        //不需要排序所以使用unordered_map
        unordered_map<int, int> mapAB ; //key:a+b的值  value:a+b数值对应出现次数
        for (int a : nums1) {
            for (int b : nums2) {
                mapAB[a + b] ++;
            }
        }
        int count = 0;  //记录满足条件四元组数量
        for (int c : nums3) {
            for (int d : nums4) {
                if (mapAB.find(0 - (c + d)) != mapAB.end())
                    count += mapAB[0 - (c + d)];
            }
        }
        return count;
    }
};

3.2 C版本

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) {
    struct hashTable* hashtable = NULL;
    for (int i = 0; i < ASize; ++i) {
        for (int j = 0; j < BSize; ++j) {
            int ikey = A[i] + B[j];
            struct hashTable* tmp;
            HASH_FIND_INT(hashtable, &ikey, tmp);
            if (tmp == NULL) {
                struct hashTable* tmp = malloc(sizeof(struct hashTable));
                tmp->key = ikey, tmp->val = 1;
                HASH_ADD_INT(hashtable, key, tmp);
            } else {
                tmp->val++;
            }
        }
    }
    int ans = 0;
    for (int i = 0; i < CSize; ++i) {
        for (int j = 0; j < DSize; ++j) {
            int ikey = -C[i] - D[j];
            struct hashTable* tmp;
            HASH_FIND_INT(hashtable, &ikey, tmp);
            if (tmp != NULL) {
                ans += tmp->val;
            }
        }
    }
    return ans;
}

3.3 Java版本

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer, Integer> mapAB = new HashMap<>(); //key:nums1和nums2中元素相加的值 value:出现次数
        int tmp, count=0; //count存放符合条件四元组的次数
        for (int a : nums1) {
            for (int b : nums2) {
                tmp = a + b;
                if (mapAB.containsKey(tmp))
                    mapAB.put(tmp, mapAB.get(tmp) + 1);
                else
                    mapAB.put(tmp, 1);
            }
        }
        for (int c : nums3) {
            for (int d : nums4) {
                tmp = c + d;
                if (mapAB.containsKey(0 - tmp))
                    count += mapAB.get(0 - tmp);
            }
        }
        return count;
    }
}

3.4 Python版本

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        # 用字典存储 nums1和nums2中元素之和,value为出现次数
        mapAB = dict()
        for a in nums1:
            for b in nums2:
                if a + b in mapAB:
                    mapAB[a + b] += 1
                else:
                    mapAB[a + b] = 1
        count = 0   #存放符合条件四元组数量
        for c in nums3:
            for d in nums4:
                tmp = 0 - (c + d)
                if tmp in mapAB:
                    count += mapAB[tmp]
        return count

3.5 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;
};

4 总结

时间复杂度:O(n2)。我们使用了两次二重循环,时间复杂度均为 O(n2)。在循环中对哈希映射进行的修改以及查询操作的期望时间复杂度均为 O(1),因此总时间复杂度为 O(n2)。

空间复杂度:O(n2),即为哈希映射需要使用的空间。在最坏的情况下,A[i]+B[j]A[i]+B[j] 的值均不相同,因此值的个数为 n2 ,也就需要 O(n2) 的空间。

看到形如:A+B…+N=0的式子,要转换为(A+…T)=-((T+1)…+N)再计算,这个T的分割点一般是一半,特殊情况下需要自行判断。定T是解题的关键。

如果还没有get到可以看Carl哥的视频讲解

By – Suki 2023/1/31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/188923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C中线程信号控制

一、场景介绍存在三个线程&#xff0c;一个主线程和两个子线程&#xff08;子线程数量不固定&#xff09;。为了节省频繁创建销毁线程造成的资源浪费&#xff0c;将这些线程设置为常驻线程。但这样引入了一个新的问题&#xff0c;如何协调这些线程完成工作。主线程内是循环检测…

Webgl实现的天气效果(下雨、下雪)

一、下雨效果如图&#xff1a; 还有一种雨水效果也不错 114 Three.js实现深度遮挡的下雨特效 | 暮志未晚-中文案例网 二、下雪的效果 57 Three.js 使用粒子实现下雪特效 | 暮志未晚-中文案例网 还有一种是通过网页CSS的形式做的2D雪效果 集合在一起的源码&#xff1a; https…

编译原理学习笔记17——语义分析和中间代码生成2

编译原理学习笔记17——语义分析和中间代码生成217.1 赋值语句的翻译17.2数组元素引用的翻译17.3 类型转换17.1 赋值语句的翻译 简单算术表达式及赋值语句 赋值语句生成三地址代码的S-属性文法 赋值语句生成三地址代码的S-属性文法 产生赋值语句三地址代码的翻译模式 产…

你真的了解工厂设计模式吗?(简单工厂模式+工厂方法模式+抽象工厂模式)

工厂解决的问题 客户端在调用是不想判断实例化哪一个类或者实例化的过程过于复杂。在工厂模式中&#xff0c;具体的实现类创建过程对客户端是透明的&#xff0c;客户端不决定具体实例化哪一个类&#xff0c;而是交由“工厂”来实例化。 简单工厂模式 类图 简单工厂模式由三类…

Git GitHub纯新手入门教程

参考视频&#xff1a;Github 新手够用指南 | 全程演示&个人找项目技巧放送_哔哩哔哩_bilibili40 分钟学会 Git | 日常开发全程大放送&个搭配GitHub_哔哩哔哩_bilibiliGit和GitHub分别是什么Git是一个运行在电脑上的版本控制软件&#xff08;保存代码各个阶段历史记录的…

在使用定时器过程中存在的那些陷阱

在使用定时器的过程中&#xff0c;如果你不了解定时器的一些细节&#xff0c;那么很有可能掉进定时器的一些陷阱里&#xff0c;函数 setTimeout 在时效性上面有很多先天的不足&#xff0c;所以对于一些时间精度要求比较高的需求&#xff0c;应该有针对性地采取一些其他的方案 …

【回眸】牛客网刷刷刷(四)软件工程(续)ZooKeeper字符串链表(专题)

前言 本篇博客为笔者刷客观笔试题时做的一些记录以供以后复习时翻阅&#xff0c;如果能够帮到您是最大的荣幸&#xff01;如果能给笔者一个三连将感激不尽&#xff01; 知识点串烧 软件工程专题&#xff08;续上篇&#xff09; 有一些可维护特性是相互促进的&#xff0c;如…

【技术美术图形部分】PBR Disney原则的BRDF 次表面散射模型

写在前面 补充去年遗漏下的知识。很多叙述都是参考了众多大佬的文章&#xff01;因为是作为个人学习总结的博客&#xff0c;所以直接卑微的借鉴过来了&#xff0c;后面会给出所有参考的文章。 另外&#xff0c;放上一个忘了在哪一篇知乎评论里的截图&#xff1a; 说的蛮好。 …

MySQL基础篇笔记

文章目录导入表的问题第3章_最基本的SELECT语句1. SQL语言的规则和规范1) 基本规则2) SQL大小写规范&#xff08;建议遵守&#xff09;3) 注释4) 命名规则2. 基本的SELECT语句1) SELECT ... FROM2) 列的别名3) 去除重复行4) 空值参与运算5) 着重号 6) 查询常数3. 显示表结构4. …

贪心算法(基础)

目录 一、什么是贪心&#xff1f; &#xff08;一&#xff09;以教室调度问题为例 1. 问题 2. 具体做法如下 3. 因此将在这间教室上如下三堂课 4. 结论 &#xff08;二&#xff09;贪心算法介绍 1. 贪心算法一般解题步骤 二、最优装载问题 &#xff08;一&#xf…

智能驾驶 车牌检测和识别(四)《Android实现车牌检测和识别(可实时车牌识别)》

智能驾驶 车牌检测和识别&#xff08;四&#xff09;《Android实现车牌检测和识别&#xff08;可实时车牌识别&#xff09;》 目录 智能驾驶 车牌检测和识别&#xff08;四&#xff09;《Android实现车牌检测和识别&#xff08;可实时车牌识别&#xff09;》 1. 前言 2. 车…

SLAM数学知识回顾

文章目录1、三角函数2、向量运算&#xff08;1&#xff09;负向量&#xff08;2&#xff09;向量的模&#xff08;3&#xff09;标量与向量的运算&#xff08;4&#xff09;标准化向量&#xff08;5&#xff09;向量的加法和减法&#xff08;6&#xff09;距离公式&#xff08;…

三十七、Kubernetes1.25中数据存储第三篇

1、概述在前面已经提到&#xff0c;容器的生命周期可能很短&#xff0c;会被频繁地创建和销毁。那么容器在销毁时&#xff0c;保存在容器中的数据也会被清除。这种结果对用户来说&#xff0c;在某些情况下是不乐意看到的。为了持久化保存容器的数据&#xff0c;kubernetes引入了…

计算机视觉OpenCv学习系列:第十部分、实时人脸检测

第十部分、实时人脸检测第一节、实时人脸检测1.OpenCV人脸检测支持演化2.OpenCV DNN检测函数3.代码练习与测试学习参考第一节、实时人脸检测 1.OpenCV人脸检测支持演化 OpenCV4 DNN模块 DNN- 深度神经网络 来自另外一个开源项目tiny dnnOpenCV3.3正式发布最新版本OpenCV4.5.…

网络编程 之 epoll

epoll 参数设置 events设置 ev.events EPOLLIN | EPOLLET;epoll实现TCP通讯时&#xff0c;events通用设置如上&#xff0c;EPOLLIN代表可socket套接字可接收数据&#xff0c;EPOLLET代表边沿触发。在服务器端, 接受客户端连接的socket不能设置为EPOLLOUT&#xff0c;只设置E…

【5】【TypeScript】(TypeScript=Type+JavaScript)

Typescript 相比js特有 类型系统&#xff1b;对象的接口DOM操作时候需要进行类型断言上面三个实际是类型系统的三处体现枚举js中&#xff0c;-号可以强制转换为数值&#xff0c;ts不行 所有合法的js都是ts 1、安装 安装进度卡住可以用淘宝镜像 &#xff08;在后面加 --registr…

Spring Cloud Hystrix有什么作用?

在微服务架构中&#xff0c;通常会存在多个服务层调用的情况&#xff0c;如果基础服务出现故障可能会发生级联传递&#xff0c;导致整个服务链上的服务不可用&#xff0c;如图1所示。图1 服务故障的级联传递在图1中&#xff0c;A为服务提供者&#xff0c;B为A的服务调用者&…

反欺诈(羊毛盾)API有什么作用?

肯定很多企业、商家都遭受过羊毛党的侵入&#xff0c;比如恶意注册、刷单、领用的行为。羊毛党具体有哪些危害呢&#xff1f; 羊毛党的危害 虚假用户裂变&#xff1a;识别在游戏解锁、红包裂变、助力砍价、电商拼团等用户拉新活动中作弊行为。虚假登录注册&#xff1a;防止机…

Java基于springboot大学生宿舍寝室考勤人脸识别管理系统

简介 Java基于springboot开发的大学生寝室管理系统宿舍管理系统。学生可以查找寝室和室友信息&#xff0c;可以申请换寝室&#xff0c;申请维修&#xff0c;寝室长提交考勤信息&#xff08;宿管确认学生考勤信息&#xff09;&#xff0c;补签&#xff0c;查看寝室通报&#xf…

FPGA纯verilog代码实现图像缩放,两种插值算法任意尺寸缩放,提供3套工程源码

目录1、设计思路和架构2、纯verilog代码搭建&#xff0c;不带任何ip3、双线性插值和邻域插值算法4、vivado和matlab联合仿真及结果5、工程代码1&#xff1a;720P原始摄像头采集显示6、工程代码2&#xff1a;720P缩小到800x600P显示7、工程代码3&#xff1a;720P缩放大1920x1080…