最接近的三数之和

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

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

 

方法一:

解题思路:

最接近的三数之和其实和三数之和的解题思路是相同的,而且要更简单,因为不需要考虑重复组合的问题,采用的都是排序加双指针的做法

(1)针对排序,采用的是快速排序,我用的是C语言实现的,所以直接调用了C语言的qsort函数直接对数组进行排序,时间复杂度是O(NLOGN);

(2)按照升序排列之后,从数组头部开始,定住一个元素,nums[ii], 然后针对该元素,遍历他的所有可能性,在遍历他所有的可能性的时候

使用双指针,左指针left指向ii+1的位置,右指针right指向numsSize-1的位置,也就是数组的最后一个元素,然后开始遍历;

(3)针对该题的遍历原则是,将每次遍历得到的sum值与target比较,如果差值等于0, 则直接返回0;如果差值不等于0, 则比较abs(sum-target)

与abs(result-target)的值,如果发现abs(sum-target)较小, 则将新得到的sum赋给result, 接着开始比较sum与target的大小,如果sum较大,则

right--; 如果sum较小, 则left++,直接left>=right, 本轮循环结束。ii++,开始新的循环,直到,ii>= numsSize-2所有的循环结束。

代码实现如下:

int cmp(const void * a, const void *b){

    return (*(int *)a - *(int *)b); 

}
int threeSumClosest(int* nums, int numsSize, int target){
    qsort(nums, numsSize, sizeof(int), cmp);
    int ii=0;
    int result=0;
    int flag=1;
    for(;ii<numsSize-2;ii++){
            int left=ii+1;
            int right=numsSize-1;
            while(left<right){
                int sum=nums[ii]+nums[left]+nums[right];
                if(sum - target == 0){
                    return target;
                }

                if(flag ==1){
// 记录是否是第一次遍历,如果是的话,则直接记录sum的结果,直接跳到sum与target比较大小的位置,不需要在比较abs(sum-target) 与 abs(result - target)
                    result=sum;
                    flag=0;
           goto not_first;
                }

                if(abs(sum-target) < abs(result - target)){
                    result=sum;
                }
not_first:
                if(sum > target){
                    right--;
                }else if(sum < target){
                    left++;
                }
            }
    }
    return result;
}



来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum-closest
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted on 2020-03-07 11:52  PigDragon  阅读(364)  评论(0编辑  收藏  举报