Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
给你一个长度为 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
二、题解:
方法一 三循环比较法
- 原理。根据所有记录三数之和,得到最小的值
- 思路。先记录所有记录三数之和,再循环判断最小的值
代码:
var threeSumClosest = function(nums, target) {
let arr = []
for(let i =0 ;i<nums.length;i++){
for(let j = i+1;j<nums.length;j++){
for(let k = j+1;k<nums.length;k++){
console.log(nums[i], nums[j], nums[k])
arr.push(nums[i]+nums[j]+nums[k])
}
}
}
let min = Math.abs(target-arr[0])
let minNum = arr[0]
for(let i = 1 ;i<arr.length;i++){
let item = arr[i]
let diffNum = Math.abs(target-item)
if(diffNum < min){
minNum = item
min = diffNum
}
}
return minNum
};
最后超时了,只能优化下
- 优化思路。循环的时候就判断最小值即可。
代码:
var threeSumClosest = function(nums, target) {
let sum = 0
let min = nums[0]+nums[1]+nums[2]
for(let i =0 ;i<nums.length-2;i++){
for(let j = i+1;j<nums.length-1;j++){
for(let k = j+1;k<nums.length;k++){
sum = (nums[i] + nums[j] + nums[k]);
if(Math.abs(target-sum) < Math.abs(target-min)){
min = sum
}
}
}
}
return min
};
方法二 双指针遍历法
- 原理。先对输入数组排序,排序后利用双指针取值计算判断。这里判断大小后需要移动指针,继续判断。
代码:
const threeSumClosest = (nums, target) => {
nums.sort((a, b) => a - b);
let min = Infinity;
const len = nums.length;
for (let i = 0; i < len; i++) {
let [left, right] = [i + 1, len - 1];
while (left < right) {
const sum = nums[i] + nums[left] + nums[right];
if (Math.abs(sum - target) < Math.abs(min - target)) {
min = sum;
}
if (sum < target) {
left++;
} else if (sum > target) {
right--;
} else {
return sum;
}
}
}
return min;
};
方案比较
方案一 时间复杂度O(n3) 方案二 时间复杂度O(n2)
三、总结
- 此题可以三循环比较法和双指针遍历法两种方案
- 三循环比较法主要是根据所有记录三数之和,得到最小的值
- 双指针遍历法先对输入数组排序,排序后利用双指针取值计算判断。这里判断大小后需要移动指针,继续判断。
文中如有错误,欢迎在评论区指正