Leetcode——16.最接近的三数之和

题目:

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

返回这三个数的和。

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

思路:

先将nums进行从小到大进行排序,然后采用固定一个位置i,其余两个位置进行双指针解法,一个指针lk = i+1,另一个rk = nums.length-1。当nums[lk]+nums[rk]+nums[i]<target时,使lk++;大于时,使rk--;相等时输出sum = nums[lk]+nums[rk]+nums[i]。

边界条件:

当sum1=nums[i]+nums[i+1]+nums[i+2] > target时,由于目前sum1是之后的所有可能的和的最小值,也就是说sum1-target会越来越大,就不会更加接近,这时只需要判断之前最接近的值finalSum和sum1谁更接近target,就输出谁。

代码:

public static int threeSumClosest(int[] nums, int target) {
        if(nums.length==3){
            return nums[0]+nums[1]+nums[2];
        }
        quickSort(nums, 0, nums.length-1);
        int min=100000;
        int sum=0;
        int finalSum=0;
        for(int i=0;i<nums.length-2;i++){
            int sum1=nums[i]+nums[i+1]+nums[i+2];
            if(sum1>=target){
                if(min>(sum1-target)){
                    return sum1;
                }else{
                    return finalSum;
                }
            }
            int lk=i+1;
            int rk=nums.length-1;
            while(lk<rk){
                sum=nums[i]+nums[lk]+nums[rk];
                if(min>Math.abs(sum-target)){
                    finalSum=sum;
                    min=Math.abs(sum-target);
                }
                if(sum==target){
                    return finalSum;
                }else if(sum<target){
                    lk++;
                }else{
                    rk--;
                }
            }
        }
        return finalSum;
    }

    private static void quickSort(int[] nums, int left, int right) {
        if(left>=right){
            return;
        }
        int pivot = paration(nums, left, right);
        quickSort(nums, left, pivot-1);
        quickSort(nums, pivot+1, right);
    }

    private static int paration(int[] nums, int left, int right) {
        int pivot = nums[left];
        while(left<right){
            while(left<right&&nums[right]>=pivot) right--;
            nums[left]=nums[right];
            while(left<right&&nums[left]<=pivot) left++;
            nums[right]=nums[left];

        }
        nums[left]=pivot;
        return left;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值