[LeetCode#16] 3Sum Closest(最接近的三数之和)

问题描述

给定一个有n个元素的整数数组nums和一个整数target,找出nums中的三个元素a、b、c,使得 a + b + c 与target距离最近,并输出这个最近的距离。
Example:nums = [-1,2,1,-4], target = 1
Result:2,其中 -1+2+1 = 2 为最近。

解决方法

这个题与LeetCode15题很类似,但也有不同。首先最容易想到的是三层循环,取三个数每次加和判断距离,然后找最短距离的那一组和,但是这个方法是行不通的,会严重超时。下面结合LeetCode15的方法,考虑先给数组排序,只需要两层循环就可以完成。具体方法如下:
第一步先对数组排序,这里直接调用排序函数, Arrays.sort(nums);
第二步外面一层循环每次取出一个元素nums[i], 里面用两个指针标识left和right,left开始指向i+1元素,r指向最后一个元素。然后三数求和sum = nums[i] + nums[left] + nums[right] , 与target判断距离:
——>如果sum=target距离就为0了,直接返回结果为sum;
——>如果sum > target,说明和sum偏大,right=right-1向左找小一点的数;
——>如果sum < target,说明和sum偏小,left=left+1向右找大一点的数;
第三步直left = right 后,回到最外面的循环继续。

代码实现

import java.util.Arrays;

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums); // 对数组进行排序
        int result = nums[0] + nums[1] + nums[nums.length - 1];
        for(int i=0; i < nums.length; i++){
            int left = i + 1;
            int right = nums.length - 1;
            while(left < right){
                int sum = nums[i] + nums[left] + nums[right];
                if(sum == target){ // 三数之和等于target时距离最近
                    return target;
                }else{
                    int dis = Math.abs(sum - target);
                    int temp = Math.abs(result - target);
                    if(dis < temp){ // 新的和比上次更接近target
                        result = sum;
                    }
                    if(sum > target){ // 和比target大,左移动减小和
                        right--;
                    }
                    else{ // 和比target小,右移动增加和
                        left++;
                    }
                }
            }
        }
        return result;
    }
}

你可能感兴趣的:(LeetCode)