前言
数据结构与算法属于开发人员的内功,不管前端技术怎么变,框架怎么更新,版本怎么迭代,它终究是不变的内容。 始终记得在参加字节青训营的时候,月影老师说过的一句话,不要问前端学不学算法。计算机学科的每一位都有必要了解算法,有
写出高质量代码的潜意识
。
一、问题描述
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入:nums = [0,0,0], target = 1 输出:0
提示:
- 3 <= nums.length <= 1000
- 1000 <= nums[i] <= 1000
- 104 <= target <= 104
二、思路讲解
这个问题三数之和
非常类似,没有做过三树之和问题的小伙伴,可以先去看这篇:力扣-三数之和题解的关键在去记录,三数之和于target之间的差值,其次采用迭代 + 双指针的方式去找到所有可能的三数之和。
优化:
- 迭代的过程其实是找 三数中的第一个数 n1,如果之前寻找过这个n1了就不需要找了,做法也很简单,给nums排个序就行。
- 和三数之和不同的是,最接近三数之和问题,两者之间的差值可能为负数,所以需要有个状态变量flag记录差值是否小于0
- 如果差值小于零,也就是我们的sum(n1 + n2 + n3) 太小了,可以让左指针往右移动,让结果变大,反之亦然
三、AC代码
时间复杂度O(nlogn) 空间 O(1)
var threeSumClosest = function(nums, target) { let res = Infinity let minPoor = Infinity nums.sort((a, b) => a - b) for(let i = 0;i< nums.length - 1; i++){ let n1 = nums[i] if(i >= 1 && n1 == nums[i - 1]) continue let left = i + 1 , right = nums.length - 1 while(left < right){ let n2 = nums[left] , n3 = nums[right] let cur = n1 + n2 + n3 let poor = cur - target let flag = false if(poor<0){ flag = true poor = -poor } if(poor<minPoor){ res = cur minPoor = poor } if(flag){ while(left < right && n2 == nums[left]) left ++ }else{ while(left < right && n3 == nums[right]) right -- } } } return res };
后续
- 地址: 寻找两个正序数组的中位数
好了,本篇 力扣-最接近三数之和
到这里就结束了,我是邵小白,一个在前端领域摸爬滚打的大三学生,欢迎👍评论。