前端算法(16)

46 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

输入: nums = [-1,2,1,-4], target = 1
输出: 2
解释: 与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

解题思路

思路一

我们可以使用双指针进行解题,首先我们先确定好双指针的位置,这也是首尾指针, 然后再使用while循环做终止条件,这是双指针的重合,在通过while循环进行逻辑处理,由于首尾指针为动态的,所以我们需要求出最近的三数之和,首先需要知道以下两点,第一点是先寻找出三数之和,是最为接近的且差值为0,第二点是外层数组遍历,动态比较绝对值最小的,待数组遍历完,返回绝对值最小的

var threeSumClosest = function(nums, target) {
    nums = nums.sort((a, b) => a - b)
    const len = nums.length
    let min = Infinity
    for (let i = 0; i < len; i++) {
        let low = i + 1
        let high = len - 1
        while (low < high) {
            let sum = nums[i] + nums[low] + nums[high]
            if (Math.abs(sum - target) < Math.abs(min - target)) {
                min = sum
            }
            if (sum === target) {
                return sum
            } else if (sum < target) {
                low++
            } else {
                high--
            }
        }
    }
    return min
};

思路二

分别定义出左侧标识,右侧标识,左侧最大值,右侧最大值,然后再使用循环去进行循环第一位数和第二位数以及第三位数,在进行求和,求和过后进行判断当前求和集合中有没有和数据相同的,在进行去重,然后取左最大取右最小与取差值进行对比,如果左侧标识为false,则表示所有三位数和都大于目标值则进行返回右侧值,如果右侧标识为false,则表示所有三位数的和都小于目标值,则返回左侧值

var threeSumClosest = function(nums, target) {
let leftFlag = false,rightFlag = false,leftMax,rightMin;
 for (var i=0;i<nums.length-2;i++){
   for (var j=i+1;j<nums.length-1;j++){
        for(var n=j+1;n<nums.length;n++){
          const total=nums[i]+nums[j]+nums[n];
          if(total==target){
             return total;
           }else if(total<target){
            leftFlag = true;
            leftMax>total?'':leftMax = total;
           }else{
             rightFlag = true;
            rightMin<total?'':rightMin = total;
           } 
        }
   } 
 }
 if(!leftFlag) return rightMin;
 if(!rightFlag) return leftMax;
 if(target- leftMax<rightMin-target){
   return leftMax
 }else{
   return rightMin
 }
}