【LeetCode】两数之和、三数之和、四数之和系列
文章目录
- 两数之和★
- 三数之和★★
- 四数之和★★
- 四数相加Ⅱ★★
- 最接近的三数之和★★
此篇文章总结下力扣中的两数之和、三数之和、四数之和及一系列求数组中满足达到目标值的元组个数的问题,仔细阅读下面的出题形式和解法,不难想到解决这类问题的思路无非是排序数组后进行相应的数组分组,双指针查找、二分法查找、或者哈希表记录。
在此说明以下题解有些是自己刷题时的思路,有些是热评,还有官方题解或者热门题解。最终版权归力扣官方所有,如有侵权敬请告知。
两数之和★
LeetCode两数之和链接
解题思路:每遍历一个元素,哈希表中保存target与已遍历元素的差和相应的下标,若哈希表中存在此元素,则找到符合条件的解,否则将差值和相应下标加入哈希表
具体代码如下:
class Solution {public int[] twoSum(int[] nums, int target) {HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>();for(int i = 0; i<nums.length; i++){if(hash.containsKey(nums[i])){return (new int[] {i, hash.get(nums[i])});}hash.put(target - nums[i], i);}return null;}
}
时间复杂度:O(n)
三数之和★★
LeetCode三数之和链接
解题思路:对数组排序后,使用双指针,并进行适当的剪枝,具体见代码
或者排序后,双重循环+二分查找也是一种思路
class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();if(nums == null || nums.length < 3) {return res;}Arrays.sort(nums);for(int i = 0; i < nums.length - 2; i++) {if(i > 0 && nums[i] == nums[i - 1]) {continue;}if(nums[i] + nums[i + 1] + nums[i + 2] > 0) {break;}//双指针int le = i + 1, ri = nums.length - 1;while(le < ri) {int sum = nums[i] + nums[le] + nums[ri];if(sum == 0) {res.add(Arrays.asList(nums[i], nums[le], nums[ri]));le++;while(le < ri && nums[le] == nums[le - 1]) {le++;}//此处先减1再执行循环可以避免越界(这样处理边界更合适)ri--;while(le < ri && nums[ri] == nums[ri + 1]) {ri--;}}else if(sum < 0) {le++;}else {ri--;}}}return res;}
}
时间复杂度:O(n²)
四数之和★★
LeetCode四数之和链接
解题思路:同三数之和一样,双重for循环 + 双指针 + 剪枝
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res = new ArrayList<>();if(nums == null || nums.length < 4) {return res;}Arrays.sort(nums);int len = nums.length;for(int i = 0; i < len - 3; i++) {if(i > 0 && nums[i] == nums[i - 1]) {continue;}if(nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {break;}if(nums[i] + nums[len - 3] + nums[len - 2] + nums[len - 1] < target) {continue;}for(int j = i + 1; j < len - 2; j++) {if(j > i + 1 && nums[j] == nums[j - 1]) {continue;}if(nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {break;}if(nums[i] + nums[j] + nums[len - 2] + nums[len - 1] < target) {continue;}int left = j + 1, right = len - 1;while(left < right) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if(sum == target) {res.add(Arrays.asList(nums[i], nums[j], nums[left],nums[right]));while(left < right && nums[left] == nums[left + 1]) {left++;}left++;while(left < right && nums[right - 1] == nums[right]) {right--;}right--;}else if(sum < target) {left++;}else {right--;}}}}return res;}
}
时间复杂度:O(n³)
四数相加Ⅱ★★
LeetCode四数相加Ⅱ链接
解题思路:先对每个数组排序,然后将A和B划分为一组,使用哈希表保存差值及差值个数(可以有相同元组,一个数组中有相同元素或不同数组有相同元素),将C和D划分为一组,其两两划分后和题目两数之和的思路一样
class Solution {public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {int count = 0;int N = A.length;Map<Integer, Integer> map = new HashMap<>();for(int i = 0; i < N; i++) {for(int j = 0; j < N; j++) {map.put(A[i] + B[j], map.getOrDefault(A[i] + B[j], 0) + 1);}}for(int i = 0; i < N; i++) {for(int j = 0; j < N; j++) {count += map.getOrDefault(-C[i] - D[j], 0);}}return count;}
}
时间复杂度:O(n²)
最接近的三数之和★★
LeetCode最接近的三数之和链接
解题思路:与三数之和思路相同,排序后使用双指针,因为是求最接近的,所以要使用做差后求绝对值来判断接近程度
以下思路及代码来自力扣热评qiyexue
class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int N = nums.length;int closestSum = nums[0] + nums[1] + nums[2];for(int i = 0; i < N - 2; i++) {int le = i + 1, ri = N - 1;while(le < ri) {int threeSum = nums[i] + nums[le] + nums[ri];if(Math.abs(threeSum - target) < Math.abs(closestSum - target)) {closestSum = threeSum;}if(threeSum < target) {le++;}else if(threeSum > target) {ri--;}else {return target;}}}return closestSum;}
}
时间复杂度:O(n²)
【LeetCode】两数之和、三数之和、四数之和系列相关推荐
- LeetCode 17电话号码的字母组合(搜索)18四数之和
电话号码的字母组合 题目描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母. 示例: 输入:"23 ...
- leetcode题刷250天(84)——454. 四数相加 II(加法分配律)
给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, j, k, l < n ...
- 一圈,两圈,三圈,四圈……
某男晚上经常到学校操场练习跑步.一天,他发现有个女孩也是如此,而且他还发现一个规律,就是这个女孩第一个礼拜每天都跑一圈,第二个礼拜每天都跑两圈,第三个礼拜每天都跑三圈-- 就在第三个礼拜的某天晚上,他 ...
- revit二次开发 创建管道三通,管道四通。两根管、三根管、四根管
创建单跟水管 /// <summary>/// 创建水管Pipe/// </summary>/// <returns></returns>public ...
- 代码随想录算法训练营第七天| 454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和
Leetcode 454.四数相加II 思路分析: 本题直观的想法是采取暴力法,四数相加就用四层for循环.虽然能得到结果,但时间复杂度为o(n4),当数组长度较大时,Leetcode便提示超时.该方 ...
- 代码随想录算法训练营day6| 454.四数相加II 383.赎金信 15.三数之和 18.四数之和
代码随想录算法训练营day6| 454.四数相加II 383.赎金信 15.三数之和 18.四数之和 LeetCode 454 四数相加II 题目链接: 454.四数相加II class Soluti ...
- (补)算法训练第七天|力扣454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和
代码随想录算法训练营第七天|力扣454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和 454.四数相加II 题目链接:四数相加II 参考:https://programmerc ...
- 代码随想录算法训练营第六天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和。
代码随想录算法训练营第六天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和. 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和 454.四数相加I ...
- 代码随想录算法训练营第⑦天 | 454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和 9.30
代码随想录算法训练营第⑦天 | 454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和 9.30 454.四数相加II 可以先用2次for循环遍历前两个数组a,b 并存储到map ...
- 算法笔记-两数之和、三数之和、四数之和(LeetCode)
两数之和 1.两数之和 题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数 ...
最新文章
- C语言中使用MySQL(Linux下)
- NLP CV ML future
- 逆向调试雷电思路总结
- 用vuejs如何实现ajax,vue.js如何实现ajax
- 在Blazor中构建数据库应用程序——第3部分——UI中的CRUD编辑和查看操作
- Firebug方便分解网页的小工具
- Javascript选择排序
- 数据库程序设计复习资料
- windows: 关于MsMpEng.exe导致“弹出USB大容量存储设备时出问题”
- 微信公众平台技术揭秘之Referer的妙用
- JavaScipt设计模式初探-代理模式(一)
- bat使用命令解析-详细(转)
- 知道路程时间求加速度_加速度位移时间的公式
- java水平测试_【考试】java基础知识测试,看你能得多少分?
- 老马的技术博客 android系统通过图片绝对路径获取URI的三种方法
- ai背景合成_ai全自动视频剪辑软件,每天批量制作800条原创视频
- webpack-webpack-dev-server
- 养生主——离散数学篇
- 让客户在微信上查看订单详情,【单据分享】让你省心又省力!
- [摘要生成]Boosting Factual Correctness of Abstractive Summarization with Knowledge Graph
热门文章
- Outlook邮箱怎么方便地发送超大附件?
- android.content.context 找不到,没有虚拟方法getBaseContext()Landroid/content/Context#litho
- Java 后台实现 发送手机短信的功能(中国网建)
- Oracle-記一下使用full join的坑
- React 路由基础--React路由介绍
- 广州大数据项目招资深大数据运维工程师
- linux下GT911触摸屏驱动优化记录
- Dell戴尔电脑打开视频软件后屏幕饱和度突然变高
- 【人工智能与深度学习】自我监督学习 - ClusterFit 和 PIRL
- linux struct sched_class