题目

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]

思路

使用两重循环分别枚举前两个数,然后在两重循环枚举到的数之后使用双指针枚举剩下的两个数。假设两重循环枚举到的前两个数分别位于下标 ii 和 jj,其中 i<ji<j。初始时,左右指针分别指向下标 j+1j+1 和下标 n-1n−1。每次计算四个数的和,并进行如下操作:

如果和等于 \textit{target}target,则将枚举到的四个数加到答案中,然后将左指针右移直到遇到不同的数,将右指针左移直到遇到不同的数;

如果和小于 \textit{target}target,则将左指针右移一位;

如果和大于 \textit{target}target,则将右指针左移一位。

使用双指针枚举剩下的两个数的时间复杂度是 O(n)O(n),因此总时间复杂度是 O(n^3)O(n
3
),低于 O(n^4)O(n
4
)。

具体实现时,还可以进行一些剪枝操作:

在确定第一个数之后,如果 \textit{nums}[i]+\textit{nums}[i+1]+\textit{nums}[i+2]+\textit{nums}[i+3]>\textit{target}nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target,说明此时剩下的三个数无论取什么值,四数之和一定大于 \textit{target}target,因此退出第一重循环;
在确定第一个数之后,如果 \textit{nums}[i]+\textit{nums}[n-3]+\textit{nums}[n-2]+\textit{nums}[n-1]<\textit{target}nums[i]+nums[n−3]+nums[n−2]+nums[n−1]<target,说明此时剩下的三个数无论取什么值,四数之和一定小于 \textit{target}target,因此第一重循环直接进入下一轮,枚举 \textit{nums}[i+1]nums[i+1];
在确定前两个数之后,如果 \textit{nums}[i]+\textit{nums}[j]+\textit{nums}[j+1]+\textit{nums}[j+2]>\textit{target}nums[i]+nums[j]+nums[j+1]+nums[j+2]>target,说明此时剩下的两个数无论取什么值,四数之和一定大于 \textit{target}target,因此退出第二重循环;
在确定前两个数之后,如果 \textit{nums}[i]+\textit{nums}[j]+\textit{nums}[n-2]+\textit{nums}[n-1]<\textit{target}nums[i]+nums[j]+nums[n−2]+nums[n−1]<target,说明此时剩下的两个数无论取什么值,四数之和一定小于 \textit{target}target,因此第二重循环直接进入下一轮,枚举 \textit{nums}[j+1]nums[j+1]。

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/4sum/solution/si-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> result = new ArrayList<>();if (nums == null || nums.length < 4) {return result;}Arrays.sort(nums);for (int i = 0; i < nums.length - 3; i++) {if (i > 0 && nums[i - 1] == nums[i] ) {continue;}if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {break;}if ((long) nums[i] + nums[nums.length - 3] + nums[nums.length - 2] + nums[nums.length - 1]  < target) {continue;}for (int j = i + 1; j < nums.length -2; j++) {if (j > i + 1 && nums[j - 1] == nums[j] ) {continue;}if ((long) nums[i] + nums[j] + nums[j + 1] + nums[ j + 2] > target) {break;}if ((long) nums[i] + nums[j] + nums[nums.length - 2] + nums[nums.length - 1] < target) {continue;}int left = j + 1;int right = nums.length - 1;while (right > left) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if (sum > target) {right--;} else if (sum < target) {left++;} else {result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;right--;left++;}}}}return result;}
}

哈希表_四数之和(待完善)相关推荐

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

    代码随想录算法训练营第七天| 哈希表理论基础 ,454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和 454.四数相加II 建议:本题是 使用map 巧妙解决的问题,好好体 ...

  2. ❤️导图整理数组6:四数组的四数之和,详解Counter类实现哈希表计数,力扣454❤️

    此专栏文章是对力扣上算法题目各种方法的总结和归纳, 整理出最重要的思路和知识重点并以思维导图形式呈现, 当然也会加上我对导图的详解. 目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解), ...

  3. Suzy找到实习了吗Day 7 | 哈希表结束啦 454. 四数相加 II,383. 赎金信,15. 三数之和,18. 四数之和

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

  4. 代码随想录哈希表——四数之和

    题目 题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等 ...

  5. 两数、三数、四数之和相关题目(Leetcode题解-Python语言)

    作为 Leetcode 的第一题,两数之和自然是知名度最高的,从两数之和出发也有不少的衍生题目,下面就让我们好好地解决它们. 1. 两数之和 class Solution:def twoSum(sel ...

  6. leetcode两数之和,三数之和,四数之和问题

    1. 两数之和 遍历数组的同时,使用字典(哈希表)记录数对应的索引,对于每一个数nums[i],判断 target-nums[i]是否在字典中,找到一个即返回.若列表中的与元素有重复也可这样处理,因为 ...

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

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

  8. leetcode系列--454.四数之和Ⅱ

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

  9. ❤️导图整理数组5: 四数之和 相比 三数之和 的大量优化, 力扣18详细注解❤️

    此专栏文章是对力扣上算法题目各种方法的总结和归纳, 整理出最重要的思路和知识重点并以思维导图形式呈现, 当然也会加上我对导图的详解. 目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解), ...

最新文章

  1. java web程序示例_想要建立一些有趣的东西吗? 这是示例Web应用程序创意的列表。...
  2. 80后的网上创业生涯:想得到做得到
  3. 外部链接linux下的mysql,Linux下mysql实现远程链接
  4. Event/window.Event属性和方法
  5. linux accept过程,Linux协议栈accept和syn队列问题
  6. 前端学习(988):jquery常见的api
  7. mysql+百万+中间表_MYSQL优化
  8. 映射到另一台计算机,远程服务器硬盘映射到本地电脑
  9. MIT 2018 自动驾驶课程
  10. 《如何阅读一本书》总结
  11. Jersey MongoDB的使用
  12. 【谷歌重磅发布2017学术影响因子】AI、视觉、机器人TOP20 榜单
  13. linux quota原理,[转载]linux下quota实现
  14. 解决 C# GetPixel 和 SetPixel 效率问题
  15. 毕业论文设置图序号为图1-1,而不是图一-1,同时设置题注方便交叉引用
  16. 在vc2008中用_crtBreakAlloc调试内存泄漏
  17. Arduino库 <TFT_eSPI> 中文字库的制作与使用
  18. 深度学习论文:Deep Residual Learning for Image Recognition
  19. 使用g++创建动态库和静态库及其相关探索
  20. 如何调出手机信任计算机的指令,苹果手机怎么连接到电脑上面去发(苹果在哪设置信任电脑)...

热门文章

  1. 使用PHP模拟post提交数据
  2. 安装青龙面板开启京东白嫖模式
  3. 如何利用长尾关键词挖掘推广口红?
  4. Linux 命令(68)—— realpath 命令
  5. mysql odbc怎么卸载_如何完全卸载数据库
  6. Linux 压缩文件和文件打包。
  7. 探讨位操作、算术右移、逻辑右移
  8. 病毒Ytnauexu
  9. Ubuntu18.04 安装 ROS Melodic(同时解决 rosdep update 问题,亲测有效)
  10. Ubuntu好用的视频播放器