最接近的三数之和(Java)

思路与算法:排序 + 双指针
当我们枚举到恰好等于 target 的 a+b+c 时,可以直接返回 target 作为答案,因为不会有再比这个更接近的值了。枚举 a,b,c 中任意元素并移动指针时,可以直接将其移动到下一个与这次枚举到的不相同的元素,减少枚举的次数。


package com.loo;

import java.util.Arrays;

public class Similar {

    public static void main(String[] args) {
        int[] arr = new int[]{-1 , 2 , 1 , -4};
        System.out.println(similar(arr , 1));
    }
    
    public static int similar(int[] arr , int target) {
        if (arr == null || arr.length <3) {
            System.out.println("maybe arr array is error!!! arr:" + arr + ",len:" + (arr!=null?arr.length:0));
            return 0;
        }
        System.out.println(Arrays.toString(arr));
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        int len = arr.length;
        int value = Integer.MAX_VALUE;
        for (int i=0;i<len;i++) {
            if (i>0 && arr[i]==arr[i-1]) {
                                // 去掉重复元素
                continue;
            }
            int l = i+1;
            int r = len - 1;
            while (l<r) {
                int sum = arr[i] + arr[l] + arr[r];
                                // 恰好等于 target 的 a+b+c 时
                if (sum == target) {
                    return target;
                }
                if (Math.abs(sum - target) < Math.abs(value - target)) {
                    value = sum;
                }
                // 如果 a+b+c≥target,那么就将 r​ 向左移动一个位置,否则左边向右移动一个位置
                if (sum > target) {
                    int r0 = r - 1;
                    while (l<r0 && arr[r0]==arr[r]) {
                        r0--;
                    }
                    r = r0;
                } else {
                    int l0 = l + 1;
                    while (l0<r && arr[l0]==arr[l]) {
                        l0++;
                    }
                    l = l0;
                }
            }
        }
        return value;
    }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值