Leetcode 16-三数之和

    题目:

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

    这是一道数组题,并和15题三数之和十分接近,因此采用的算法思想也十分接近,都是三指针遍历,分别为i指向最小位,j为中间位,k为最大位。遍历的情况可分为三种:

    1.nums[i]+nums[j]+nums[k]==target,由于答案唯一,此即为最接近答案,直接return。

    2.nums[i]+nums[j]+nums[k]>target,我们的目的时找到离target最近的三个数,因此需要使得nums[i]+nums[j]+nums[k]-target更加贴近0,而此时三数之和与target之差已经大于0,所以要降低三个数的和,于是需要将k向左拨,k--;

    3.  2.nums[i]+nums[j]+nums[k]<target,同理,我们要将三数之和与target的差更贴近0,所以要加大三数的和,于是需要将j右拨,j++;

    和15题一样,要考虑重复的问题,所以需要加上邻位判定。在此就不赘述。

    贴上代码。

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        int i;
        int j;
        int k;
        int result=nums[0]+nums[1]+nums[2];//初始值
        int min=Math.abs(nums[0]+nums[1]+nums[2]-target);//初始值
        Arrays.sort(nums);  
        
        for(i=0;i<nums.length-2;){
            j=i+1;
            k=nums.length-1;
            
            while(j<k){
                if(nums[i]+nums[j]+nums[k]==target){
                    return nums[i]+nums[j]+nums[k];
                }
                else if(nums[i]+nums[j]+nums[k]>target){//a+b+c-target>0情况,要将k左拨,才能更贴近0
                    
                    if(Math.abs(nums[i]+nums[j]+nums[k]-target)<min)
                    {
                        min=Math.abs(nums[i]+nums[j]+nums[k]-target);//记录最小值
                         result=nums[i]+nums[j]+nums[k];                                            
                    }
                    k--;
                    while(j<k&&nums[k]==nums[k+1]){
                        k--;
                    }  
                }
                
                else if(nums[i]+nums[j]+nums[k]<target){//a+b+c-target<0情况,要将j右拨,才能更贴近0
                    if(Math.abs(nums[i]+nums[j]+nums[k]-target)<min)
                    {
                        min=Math.abs(nums[i]+nums[j]+nums[k]-target);//记录最小值
                       result=nums[i]+nums[j]+nums[k];                                                
                    }
                   j++;
                    while(j<k&&nums[j]==nums[j-1]){
                        j++;
                    }
                }
            }
            i++;
            while(i<nums.length-2&&nums[i]==nums[i-1]){
                i++;
            }
        }
        return result;
    }
}

    提交结果如下:


          结论:排名更靠前的提交记录基本用到类似的思想,不过增加了更多情况的出口,减少了时间复杂度,但大体来说都是一样的。


猜你喜欢

转载自blog.csdn.net/huanglaopifu666/article/details/80067473