算法题:16. 最接近的三数之和(题目+思路+代码+注释)时空击败98%、91%用户(双指针思路)
题目
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
提示:
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum-closest
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
- 穷举方法就是三层循环全部试一遍,既然是个算法题,那肯定不能这样简单粗暴呀
- 问题拆分:既然要找三个数最近的,我们可以固定第一个数,拿target 减去第一个数,然后把求三个数的问题变为求后面两个数最近的值,再去和历史记录里最近的比较就可以找出最近的三个数了。
- 找后面两个数的时候如果说要遍历暴力穷举还是跟之前的三层循环一样的简单粗暴了,那么我们如何去减少不必要的比较和运算呢?既然要靠近,那么我可以先对数组排序,这样我就可以用双指针取一个小的一个大的,判断,大了的话就是要减小值,也就是右指针往左移动就可以减小值了,小了的时候左指针往右边移动就增大,这样就能更快速的找出三数之和最近的和。
代码
public int threeSumClosest(int[] nums, int target) {
//排序
Arrays.sort(nums);
int len = nums.length;
int closest = nums[0] + nums[1] + nums[2];
int gap = Math.abs(target - closest);
for (int i = 0,maxLeft = nums.length-2,t,g; i < maxLeft;i++){
int sum = target - nums[i];
for (int j = i+1,k = nums.length-1;j < k;){
t = nums[j] + nums[k];
if (t == sum ){
//相等的情况
return target;
}
if (t < sum){
//左指针右移到不相同的值
while (j+1 < len && nums[j] == nums[j+1]) {
j++;
}
j++;
}else {
//右指针左移到不相同的值
while (k - 1 > j && nums[k] == nums[k-1]){
k--;
}
k--;
}
//记录最相近的
g = Math.abs(target - t - nums[i]);
if (g < gap){
gap = g;
closest = t + nums[i];
}
}
}
return closest;
}
本文来自博客园,作者:HumorChen99,转载请注明原文链接:https://www.cnblogs.com/HumorChen/p/18039581
分类:
Java
, leetcode算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2019-07-27 步步截图的SMM框架入门实战指引(SpringBoot、Mybatis Plus、Maven)