【算法】3Sum Closest 最接近的三数之和
文章目录
- 3Sum Closest 最接近的三数之和
- 问题描述:
- 分析
- 代码
- 二分
- 双指针
- Tag
3Sum Closest 最接近的三数之和
问题描述:
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
3 < = n u m s . l e n g t h < = 3000 − 1000 < = n u m s [ i ] < = 1000 − 1 0 4 < = t a r g e t < = 1 0 4 3 <= nums.length <= 3000\\ -1000 <= nums[i] <= 1000\\ -10^4 <= target<= 10^4 3<=nums.length<=3000−1000<=nums[i]<=1000−104<=target<=104
分析
基本结构和3Sum很类似,但是数据规模缩小了。
暴力的过程依然是 O ( N 3 ) O(N^3) O(N3).
还是和昨天一样,先排序,利用双指针的结构来处理,整体的时间复杂度 O ( N 2 ) O(N^2) O(N2)。
这里双指针寻找的yz组合,要求是xyz和最靠近target,即y+z最接近 ∣ t a r g e t − x ∣ |target-x| ∣target−x∣。
所以在固定x之后,固定y,然后双指针处理寻找yz组合。也就是双指针在不断的枚举可能的yz组合,并且记录xyz结果。
双指针部分的加速,当然也可以选择不加速,数据规模也可以允许。
为了加速,当 x = n u m [ i ] , y = n u m [ i + 1 ] , z = n u m [ i + 2 ] , s u m = x + y + z > t a r g e t x= num[i],y=num[i+1],z=num[i+2],sum=x+y+z>target x=num[i],y=num[i+1],z=num[i+2],sum=x+y+z>target,此时已经找到了一个比target大的最小的组合,所以后面就不用遍历了。
当 x = n u m [ i ] , y = n u m [ n − 2 ] , z = n u m [ n − 1 ] , , s u m = x + y + z < t a r g e t x= num[i],y=num[n-2],z=num[n-1],,sum=x+y+z<target x=num[i],y=num[n−2],z=num[n−1],,sum=x+y+z<target,说明此时固定x的最大组合都比target小,此时的xyz就是当前固定x的最佳组合,但是依旧需要继续遍历i.
当然也可以使用二分,理论上的时间复杂度是 O ( N 2 L o g N ) O(N^2LogN) O(N2LogN),。
代码
二分
public int threeSumClosest(int[] nums, int target) {int n = nums.length,ans = 1<<30,diff=1<<30;if(n==3) return nums[0]+nums[1]+nums[2];Arrays.sort(nums); for(int i= 0;i<n-2;i++){ if(i>0&&nums[i]==nums[i-1]) continue; int sum = nums[i]+nums[i+1]+nums[i+2];if(sum>=target){ return sum-target<diff?sum:ans;}sum = nums[i]+nums[n-1]+nums[n-2];if(sum<target){ int d = target - sum;if(d<diff){ans = sum; diff = d;} continue;}for(int j = i+1;j<n-1;j++){int z = find(nums,j+1,n-1,target-nums[i]-nums[j]);sum = nums[i];sum+= nums[j];sum+= z;if(sum==target) return target;int d = Math.abs(sum-target);if(d<diff){ans = sum;diff = d;} } }return ans;}// find 1st >= targetpublic int find(int[] arr, int left ,int right,int target){if(arr[left]>target) return arr[left];if(arr[right]<target) return arr[right];int mid = 0,l = left,r = right;while(l<r){mid = l+(r-l)/2;if(arr[mid]<target){l = mid+1;}else{r = mid;}}if(l>left){if( Math.abs(arr[l-1] -target)<=Math.abs(arr[l] -target) ){return arr[l-1];} }return arr[l];}
时间复杂度 O ( N 2 log N ) O(N^2 \log N) O(N2logN)
空间复杂度 O ( log N ) O(\log N) O(logN)
双指针
public int threeSumClosest(int[] nums, int target) {int n = nums.length,ans = 1<<30,diff=1<<30;if(n==3) return nums[0]+nums[1]+nums[2];Arrays.sort(nums); for(int i=0; i<n-2; i++){if(i>0&&nums[i]==nums[i-1]) continue;int j=i+1,k=n-1;//加速int sum = nums[i]+nums[i+1]+nums[i+2];if(sum>=target){return sum-target<diff?sum:ans;}sum = nums[i]+nums[n-1]+nums[n-2];//加速if(sum<target){ int d = target - sum;if(d<diff){ans = sum; diff = d;} continue;}while(j<k){sum = nums[i]+nums[j]+nums[k];int d = Math.abs(sum - target);if(d<diff){diff = d;ans = sum;}if(sum==target){return target;}else if(sum>target){k--;while(j<k&& nums[k]==nums[k+1]){k--;} }else{ j++;while(j<k&& nums[j-1]==nums[j]){j++;} }}} return ans;}
时间复杂度 O ( N 2 ) O(N^2) O(N2)
空间复杂度 O ( log N ) O(\log N) O(logN)
加速部分,思路启发来源灵神
Tag
Array
Two Pointers
Sort
【算法】3Sum Closest 最接近的三数之和相关推荐
- 16. 3Sum Closest 最接近的三数之和
Title 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. ...
- leetcode 16. 3Sum Closest | 16. 最接近的三数之和(双指针)
题目 https://leetcode.com/problems/3sum-closest/ 题解 方法1:固定 L,双指针找 M.R 时间复杂度 O(n^2),推荐此方法. 证明不会有元素遗漏,详见 ...
- Leetcode算法Java全解答--16. 最接近的三数之和
Leetcode算法Java全解答–16. 最接近的三数之和 文章目录 Leetcode算法Java全解答--16. 最接近的三数之和 题目 想法 结果 总结 代码 我的答案 暴力破解 滑动列表 大佬 ...
- python【力扣LeetCode算法题库】16- 最接近的三数之和
最接近的三数之和 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答 ...
- 算法:最接近的三数之和
题目: 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 示例 ...
- 【算法系列之十二】最接近的三数之和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 例如,给定数 ...
- [Leetcode16]最接近的三数之和
[Leetcode16]最接近的三数之和 转载自leetcode https://leetcode-cn.com/problems/3sum-closest/ 1.题目 给定一个包括 n 个整数的数组 ...
- 领扣LintCode问题答案-59. 最接近的三数之和
领扣LintCode问题答案-59. 最接近的三数之和 目录 59. 最接近的三数之和 鸣谢 59. 最接近的三数之和 给一个包含 n 个整数的数组 S, 找到和与给定整数 target 最接近的三元 ...
- LeetCode 15三数之和16最接近的三数之和
三数之和(双指针) 题意: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意 ...
最新文章
- 24核服务器配什么系统,24核服务器
- css菜单缓慢滑动_如何使用HTML,CSS和JavaScript构建滑动菜单栏
- 程序猿修仙之路--算法之直接插入排序
- 百度ERNIE新突破,登顶中文医疗信息处理权威榜单CBLUE冠军
- Java Maximum Subarray debug
- 洛谷.4172.[WC2006]水管局长(LCT Kruskal)
- [FPGA]基于FPGA的数字跑表
- 【Java】浅析八种基本类型
- MCMS 基于SpringBoot 2架构
- com.android.mms 占cpu,怎么CPU占用这么高啊!
- pom.xml中出现错误提示Failure to transfer org.jboss.weld.jar ... maven2 was cached in the local repository.
- vue-cli脚手架npm run build打包后图片路径问题 2018.11.21
- 【转】 VS2005中ajax安装指南
- VOSviewer:高频关键字段共现网络制作入门教程(以PubMed数据为例)
- 开源| 直播推拉流2.0升级了什么
- 前端学习-jquery-实现点击button对文本的add及detele
- 编写一个计算图形面积和周长的程序
- 计算机文件夹添加密码,电脑如何给文件夹设置密码
- 商用计算机品牌,请问什么牌子的笔记本比较好啊?要商用的
- Python系列-Django-Ninja