LeetCode-16. 3Sum Closest

恩,先夸一下leetcode,真的比lintcode强不少,无论是题的质量还是代码judging的速度来说。

来,切入正题。


16 .

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).

这道题出的还是蛮有意思的,不跟以前的题一样一看就有思路。
首先看到题的第一反应就是遍历,但是想想3个数字遍历起来估计复杂度o(n^3),数组一大直接爆炸,不可以用这个方法。
搞定,附上代码,回头写思路。(赶着出去吃宵夜)

吃饱回来惹,这边的烧烤真心比深圳的好吃多了…还便宜。

好了废话不多说,继续上面的。
然后决定,先排序。(嗯没错,幸亏我之前机智的把排序复习了一波,现在直接ctrl+c,ctrl+v)
排序完了之后,每次固定一个数字i,然后另外两个数字,一个为前面固定的值的位置+1,为left;另外一个数字为数组最后一个值,为right。
然后计算i+left+right,如果大于target,那么就right–,小于target就left++;如果等于的话直接两次return出去return target;
i这么遍历完以后,再i+1继续…直到结束。
按这个方法遍历,然后每次计算D值(与target的差),都记着最小的D值的sum。最后返回sum即可。
嗨呀语言真的特别难描述算法这种东西,直接看代码吧。


public class Solution {

    public static void main(String[] args) {

    int [] nums={0,0,0};
    int target=1;
    Solution s=new Solution();
    System.out.println(s.threeSumClosest(nums, target));

    }


    public int threeSumClosest(int[] nums, int target) {

        quickSort(nums);
        int nowSum=0;
        int D=Integer.MAX_VALUE;
        int minDSum=Integer.MIN_VALUE;
        for(int i=0,l=nums.length;i<l;i++){
            if(-2147483648==getMinDSum(i,nums,target)){
            continue;
            }
            nowSum=getMinDSum(i,nums,target);
            if(nowSum==target){
                return nowSum;
            }
            if(getD(nowSum,target)<D){
                minDSum=nowSum;
                D=getD(nowSum,target);
            }

        }
        return minDSum;

    }

    private static int getMinDSum(int i,int[] nums,int target){
        //return : sum of three nums such that closest to target 



        int left=i+1;
        int right=nums.length-1;
        int nowSum=0;
        int D=Integer.MAX_VALUE;
        int minDSum=Integer.MIN_VALUE;
        while(right>left){
            nowSum=nums[i]+nums[left]+nums[right];
            if(nowSum==target){
                return nowSum;
            }

            if(getD(nowSum,target)<D){
                D=getD(nowSum,target);
                minDSum=nowSum;
            }

            if(nowSum>target){
                right--;
            }else if(nowSum<target){
                left++;
            }


        }



        return minDSum;

    }

    private static int getD(int a,int b){
            return  (a>b?a:b)-(a>b?b:a);  
    }




    private static void quickSort(int[] arr) {

    qs(arr, 0, arr.length - 1);

    }

    private static void qs(int[] arr, int start, int end) {

    if (start == end) {
        return;
    }

    int base = start;
    int left = start + 1;
    int right = end;

    while (true) {

        while ((arr[right] >= arr[base]) && (right > left)) {
        right--;

        } 
        while ((arr[left] <= arr[base]) && (left < right)) {
        left++;
        } 

        if (right == left) {
        if (arr[left] < arr[base]) {
            int tmp = arr[base];
            arr[base] = arr[left];
            arr[left] = tmp;
        }
        break;
        } else {
        int tmp = arr[right];
        arr[right] = arr[left];
        arr[left] = tmp;
        }

    }

    qs(arr, start, right - 1);
    if (right  > end) {
        qs(arr, end, end);
    } else {
        qs(arr, right , end);
    }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值