新手做LeetCode N16 3Sum Closest

先贴个题目和答案。

/**
 * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target.
 * Return the sum of the three integers.
 * You may assume that each input would have exactly one solution.
    For example, given array S = {-1 2 1 -4}, and target = 1.
    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
 *
 */

public class N16_3Sum_Closest {

    
     public int threeSumClosest(int[] nums, int target) {
            Arrays.sort(nums);
            if(nums == null || nums.length == 0)
            {
                return 0;
            }

            int closest = nums[0] + nums[1] + nums[2];
            int diff = Integer.MAX_VALUE;
            for(int i = 0 ; i < nums.length - 2; i++)
            {
                int left = i + 1;
                int right = nums.length - 1;
                while(left < right )
                {
                    int sum = nums[i] + nums[left] + nums[right];
                    //如果总和大于target,那么左边越小越好,所以减小right
                    if(sum > target)
                    {
                        if(sum - target < diff )
                        {
                            //到达了这个点
                            diff = sum - target;
                            closest = sum;
                        }
                        right -- ;
                    }
                    else if(sum < target){
//                        System.out.println("left = " + left);
//                        System.out.println("right = " + right);
                        if( target - sum < diff)
                        {
                            diff = target - sum;
                            closest = sum;
                        }
                        left ++ ;
                }
                    else{
                        return target;
                    }
                }
            }
         
         return closest;
        
    }
    
    public static void main(String[] args) {
        int[] test = {
                0,0,0
        };
        int[] test2 = {
                0,2,1,-3
        };// target = 1;
        int[] test3 ={
                1,2,4,8,16,32,64,128
        };//target = 84;
        int[] test4 = {
                87,6,-100,-19,
                10,-8,-58,56,14,-1,-42,-45,-17,10,
                20,-4,13,-17,0,11,-44,65,74,-48,30,-91,13,-53,76,-69,-19,
                -69,16,78,-56,27,41,67,-79,-2,30,-13,-60,39,95,64,
                -12,45,-52,45,-44,73,97,100,-19,-16,-26,58,-61,53,70,
                1,-83,11,-35,-7,61,30,17,98,29,52,75,-73,-73,-23,-75,91,
                3,-57,91,50,42,74,-7,62,17,-91,55,94,-21,-36,73,19,-61,
                -82,73,1,-10,-40,11,54,-81,20,40,-29,96,89,57,10,-16,-34,
                -56,69,76,49,76,82,80,58,-47,12,17,77,-75,-24,11,-45,60,
                65,55,-89,49,-19,4
        };//target = - 275
        int[] test5 = {
                0,1,2
        };//target = 0 检查边界条件thisClosest是否正确初始化
        int[] test6 = {
                0,0,0
        };//target = 1
        int[] test7 = {
                -100,-90,-90,-88,-70,0,10,22,22,22,33,34
        };//target = -260
        System.out.println("closest = " + new N16_3Sum_Closest().threeSumClosest(test4,-275));
        Arrays.sort(test4);
        for(int i = 0; i < test4.length ; i ++)
        {
            System.out.print(test4[i] + ",");
            if(i % 10 == 0)
            {
                System.out.println();
            }
        }
    }
}


题意是让你从给定的数组里找出三个数,要求这三个数的和要和给定的一个target最接近。要返回这三个数的和。


这道题用从15题学来的遍历方法,避免超时。这道题花了我很长时间,一开始走偏了道路。我试图从数学的角度来做这个题,做了如下的图:




错误是从这里开始的——试图寻找target这个点或者是target左右的两个点。于是就陷入了混乱中。最终通过看discuss才找到了方向:全部遍历一遍,而不是试图通过这个图像来找到答案。此方法的缺陷在于,对于target = 0,答案1和-1都是成立的,但只能找出一个来。


现在,如果要通过这个图像来寻找答案的话,首先需要找到所有的和,记下他们中大于target的最小的,记下小于target中的最大的。然后让他们进行比较即可找到,此方法可以找出两个答案来。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值