首页 > 试题广场 >

最接近的三数之和

[编程题]最接近的三数之和
  • 热度指数:1408 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个数组 nums 和一个目标值 target ,请问从 nums 中选出三个数,使其之和尽量接近目标数,即三数之和与目标数只差绝对值尽可能小。

返回满足题面要求的三数之和。

数据范围:数组长度满足 ,数组中的值满足 ,目标值满足 ,可以保证只有一个结果。
示例1

输入

[-1,2,1,-4],1

输出

2

说明

最接近 1 的三数之和是 -1+2+1 = 2  
示例2

输入

[0,0,0],1

输出

0

说明

 只有一种选择 0+0+0  
示例3

输入

[0,1,0,0],0

输出

0
穷举最小数的可能性,然后通过双指针确定中间数和最大数
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @param target int整型 
     * @return int整型
     */
    public int ClosestSum (int[] nums, int target) {
        // write code here
        int n = nums.length;
        Arrays.sort(nums);
        int res = nums[0] + nums[1] + nums[2];
        for(int first = 0; first < n; first++){
            int second = first + 1, third = n - 1;
            while(second < third){
                int tempSum = nums[first] + nums[second] + nums[third];
                if(Math.abs(target - tempSum) < Math.abs(target - res)){
                    res = tempSum;
                }
                if(tempSum > target){
                    third--;
                }else if(tempSum < target){
                    second++;
                }else{
                    return res;
                }
            }
        }
        return res;
    }
}

发表于 2021-12-22 23:17:41 回复(0)
脑溢血解法:暴力回溯,并优化(找到最优值直接返回),代码竟然一遍过,\惊喜

public static int resSum = Integer.MAX_VALUE;

    public int ClosestSum(int[] nums, int target) {
        // write code here
        boolean[] isUsed = new boolean[nums.length];
        // 暴力全量收集
        LinkedList<Integer> currList = new LinkedList<>();
        recursiveHelper(nums, isUsed, currList, target);
        return resSum;
    }

    public static boolean recursiveHelper(int[] nums, boolean[] isUsed,
                                          LinkedList<Integer> currList, int target) {
        if (currList.size() == 3) {
            int sum = 0;
            for (Integer i : currList)
                sum += i;
            int currAbs = Math.abs(sum - target);
            // 表示找到最优解
            if (currAbs == 0) {
                resSum = sum;
                return true;
            }
            int lastAbs = Math.abs(resSum - target);
            resSum = currAbs < lastAbs ? sum : resSum;
            return false;
        }

        int len = nums.length;
        for (int i = 0; i < len; i++) {
            if (isUsed[i])
                continue;
            isUsed[i] = true;
            currList.addLast(nums[i]);
            boolean res = recursiveHelper(nums, isUsed, currList, target);
            if (res)
                return true;
            else {
                // 回溯,尝试其他
                isUsed[i] = false;
                currList.removeLast();
            }

        }
        return false;
    }





编辑于 2024-04-25 15:22:37 回复(0)
export function ClosestSum(nums: number[], target: number): number {
    // write code here
    nums.sort((a,b)=>a-b)
    let result:number=nums[0]+nums[1]+nums[2]
    let oldDiff=Math.abs(target-result)
    for(let i=0;i<nums.length-2;i++){
        let left=i+1,right=nums.length-1
        while(left<right){
            let sum=nums[i]+nums[left]+nums[right]
            let newDiff=Math.abs(sum-target)
            if(newDiff<oldDiff){
                result=sum
                oldDiff=newDiff
            }
            if(sum>target)right--
            else left++
        }
    }
    return result
}
发表于 2023-06-22 20:41:36 回复(0)
package main

import "sort"
import "math"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param target int整型 
 * @return int整型
*/
func ClosestSum( nums []int ,  target int ) int {
    sort.Ints(nums)
    ans:=math.MaxInt32
    for i:=0;i<len(nums);i++{
        if i>0&&nums[i]==nums[i-1]{
            continue
        }
        sum:=0
        l,r:=i+1,len(nums)-1
        for l<r{
            sum=nums[i]+nums[l]+nums[r]
            if abs(sum,target)<abs(ans,target){
                ans=sum
            }
            if sum==target{
               return sum
            }else if sum>target{
                r--
            }else{
                l++
            }
        }
    }
    return ans
}

func abs(a,b int)int{
    if a>b{
        return a-b
    }
    return b-a
}

发表于 2023-03-14 21:11:29 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param numsLen int nums数组长度
 * @param target int整型 
 * @return int整型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
#include<math.h>
int cmp(const void*a,const void*b){
    return(*(int*)a)-(*(int*)b);
}
int ClosestSum(int* nums, int numsLen, int target ) {
qsort(nums,numsLen,sizeof(nums[0]),cmp);
int i,j,k,sum,res;  

res=nums[0]+nums[1]+nums[2];

    for(i=0;i<numsLen;i++){
        j=i+1;
        k=numsLen-1;
        
      
        while(j<k){
              sum=nums[i]+nums[j]+nums[k];
            if(abs(sum-target)<abs(res-target)){
                res=sum;
            }
            if(sum>target){
                k--;
            }
            if(sum<target){
                j++;
            }
            if(sum==target){
                return sum;
            }
        }
     }
    return res;
}

发表于 2022-08-10 23:24:08 回复(0)
class Solution:
    def ClosestSum(self , nums: List[int], target: int) -> int:
        # write code here
        nums.sort()
        res = nums[0]+nums[1]+nums[2]
        for i in range(len(nums)-2):
            start, end = i+1, len(nums)-1
            while start < end:
                tmp = nums[i]+nums[start]+nums[end]
                if abs(tmp-target) < abs(res-target):
                    res = tmp
                if tmp > target:
                    end -= 1
                elif tmp < target:
                    start += 1
                else:
                    return res
        return res

发表于 2022-07-24 17:14:00 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @param target int整型 
     * @return int整型
     */
    int ClosestSum(vector<int>& nums, int target) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        int res=nums[0]+nums[1]+nums[2];
        for(int i=0;i<n;i++){
            if(i>0&&nums[i]==nums[i-1]){
                continue;
            }
            int j=i+1,k=n-1;
            while(j<k){
                int sum=nums[i]+nums[j]+nums[k];
                if(abs(sum-target)<abs(res-target)){
                    res=sum;
                }
                if(res==target){
                    return target;
                }else if(sum>target){
                    k--;
                }else if(sum<target){
                    j++;
                }
            }
        }
        return res;
    }
};

发表于 2022-05-10 21:09:33 回复(0)
排序+双指针
public class Solution {
    public int ClosestSum (int[] nums, int target) {
        Arrays.sort(nums);
        int min = Integer.MAX_VALUE, res = 0;
        for (int i = 0; i < nums.length-2; i++) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            int start = i + 1, end = nums.length-1, sum = 0, dif = 0;
            while (start < end) {
                sum = nums[i] + nums[start] + nums[end];
                dif = Math.abs(sum-target);
                if (dif < min) {
                    min = dif;
                    res = sum;
                }
                if (sum > target) {
                    end--;
                    while (start < end && nums[end+1]== nums[end]) end--;
                } else if (sum < target) {
                    start++;
                    while (start < end && nums[start-1]== nums[start]) start++;
                } else return target;
            }
        }
        return res;
    }
}

发表于 2022-02-08 15:15:12 回复(0)

问题信息

难度:
8条回答 3547浏览

热门推荐

通过挑战的用户

查看代码