当前位置: 首页 > news >正文

Leetcode刷题 由浅入深之哈希法——454. 四数相加Ⅱ

目录

(一)四数相加的C++实现

写法一(哈希映射)

简化版:

(二)复杂度分析

时间复杂度

空间复杂度

(三)总结


【题目链接】454. 四数相加Ⅱ - 力扣(LeetCode)

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

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

示例 1:

输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

示例 2:

输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1

  提示:

  • n == nums1.length
  • n == nums2.length
  • n == nums3.length
  • n == nums4.length
  • 1 <= n <= 200
  • -228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228

(一)四数相加的C++实现

写法一(哈希映射)

解题思路:

        上一篇写过两数相加(Leetcode刷题 由浅入深之哈希法——1. 两数之和-CSDN博客)的算法,我们是将遍历过的数字存储在映射中,key为元素的值,value为数字在数组中对应的索引,循环过程中,使用target减去其中一个数字,去找另一个符合要求的数字。此题,我们也可以采用类似的方法。

        此题是从四个数组中分别选一个数字,要求四个数字之和为target。为了节省时间,我们将前两个数组的所有组合之和,以及对应的索引存储在nums_map1中;利用后两个数组的所有组合之和计算出符合要求的前两个数字之和,并在nums_map1中寻找。

        本题目只需要计数,而不需要返回每一种解的下标,因此直接设置一个计数变量count,若在nums_map1中找到加1即可。

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, vector<vector<int>>> nums_map1;for(int i=0; i < nums1.size(); i++){for(int j=0; j < nums2.size(); j++){nums_map1[nums1[i] + nums2[j]].push_back({i,j});}}int count = 0;for(int i=0; i < nums3.size(); i++){for(int j=0; j < nums4.size(); j++){int temp = - nums3[i] - nums4[j];if(nums_map1.find(temp) != nums_map1.end())count += nums_map1.find(temp)->second.size();}}return count;}
};

简化版:

        本题目只要求输出一共有几种解法,因此,在定义nums_map1时,value直接定义为整型即可,计算出符合要求的解法直接+1计数即可。

        在遍历过程中,数组中的元素需要参与计算,因此可以直接使用auto遍历元素。

改进以上两点,更简明的代码如下:

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> nums_map1;for(auto i : nums1){for(auto j : nums2)nums_map1[i + j]++;}int count = 0;for(auto i : nums3){for(auto j : nums4)count += nums_map1[-(i + j)];}return count;}
};

(二)复杂度分析

时间复杂度

        双重循环,整个函数的时间复杂度为 O(n_1n_2+n_3n_4)。通常情况下,如果四个数组的长度都为 n,那么时间复杂度可以简化为O(n^2)

空间复杂度

        哈希表占用的空间:使用 unordered_map 来存储 nums1 和 nums2 中元素两两相加的结果及其出现的次数。在最坏的情况下,nums1 和 nums2 中元素两两相加的结果都不相同,哈希表中需要存储 n1∗n2 个键值对。因此,哈希表所占用的空间复杂度为O(n_1n_2)

        其他变量占用的空间:除了哈希表之外,代码中只使用了一个整型变量 count 来记录满足条件的元组数量,其所占用的空间是常数级别的,不随数组长度的增加而增加。

综上,该函数的空间复杂度为 O(n_1n_2)。如果四个数组的长度都为 n,那么空间复杂度可以简化为 O(n^2)

(三)总结

(1)使用迭代器遍历或许更方便。

(2)映射map数据结构中的key和value类型是可以自定义的。unordered_map的基础使用方法见Leetcode刷题 由浅入深之哈希法——1. 两数之和-CSDN博客。

(3)看题目时,注意观察题目想考察的思想,多注意题目要求的输出,可以更直接地简化代码。

学习中,诚挚希望有心者指正和交流,经验或者方法都可。

http://www.xdnf.cn/news/155539.html

相关文章:

  • Logi Options+ 的 Flow:端口信息
  • 驱动开发(1)|鲁班猫rk356x内核编译,及helloworld驱动程序编译
  • 微信小程序核心技术栈
  • ORACLE数据库备份入门:第四部分:2-备份场景举例
  • 计算机视觉——对比YOLOv12、YOLOv11、和基于Darknet的YOLOv7的微调对比
  • MyBatis 官方子项目详细说明及表格总结
  • JavaScript基础知识合集笔记1——数据类型
  • TDengine 中的压缩设计
  • 毕业项目-Web入侵检测系统
  • 关于TCP三次握手和四次挥手的疑点
  • 游戏状态管理:用Pygame实现场景切换与暂停功能
  • Unity-Shader详解-其一
  • MySQL多查询条件下深度分页性能优化技巧及示例总结
  • Pytorch(无CPU搭建)+Jupyter
  • Unity-Shader详解-其二
  • 【WLAN】华为无线AC双机热备负载分担—双链路热备份
  • 【数据融合】基于拓展卡尔曼滤波实现雷达与红外的异步融合附matlab代码
  • C++异步并发支持库future
  • 探针台的具体分类有哪些
  • 基于pandoc的MarkDown格式与word相互转换小工具开发(pyqt5)
  • AAAI2016论文 UCO: A Unified Cybersecurity Ontology
  • Eclipse 插件开发 1
  • MEME在线进行蛋白氨基酸序列的保守基序预测的具体分析步骤
  • 【Tauri】桌面程序exe开发 - Tauri+Vue开发Windows应用 - 比Electron更轻量!8MB!
  • 提取PPT图片
  • 数据库监控功能-oracle
  • 【多线程】五、线程同步 条件变量
  • Unity之基于MVC的UI框架-含案例
  • mac笔记本安装brew、nvm、git等完整版
  • C#里使用libxl来创建EXCEL文件然后发送到网络