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

 

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

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

思路:

  1. 排序
  2. a递增_bc左右双指针收拢
  3. 单次二分查找试探跳步减少时间复杂度
  4. 重复值跳跃(未写)
function threeSumClosest($nums, $target) {
        //双指针方式+二分查找试探跳步检索
        sort($nums);
        $n=count($nums);
        $nearNumber=$nums[0]+$nums[1]+$nums[2];
        $diffMin=abs($nearNumber-$target);
        if(!$diffMin){
            return $nearNumber;
        }
        for($i=0;$i<$n-2;$i++){
            $a=$i;
            $b=$i+1;
            $c=$n-1;
            while($b<$c){
                $sum=$nums[$a]+$nums[$b]+$nums[$c];
                $diff=$sum-$target;
                if(!$diff)return $target;
                if($sum<$target){
                    //尝试二分判断
                    $step=(int)(($b+$c)/2);
                    if($step>$b && $nums[$step]-$nums[$b]+$diff<0){
                        $b=$step;
                    }else{
                        // do{
                            $b++;
                        // }while($b+1<$c&&$nums[$b+1]===$nums[$b]);//同值sum计算暂时不写了,之后补上
                        
                    }
                    if($diffMin> -$diff){
                        $diffMin= -$diff;
                        $nearNumber = $sum ;   
                    }
                }else{
                    //尝试二分判断
                    $step=(int)(($b+$c)/2);
                    if($step<$c && $nums[$c]-$nums[$step]-$diff<0){
                        $c=$step;
                    }else{
                        // do{
                             $c--;
                        // }while($c-1>$b && $nums[$c-1]===$nums[$c]);
                        
                    }
                    if($diffMin> $diff){
                        $diffMin= $diff;
                        $nearNumber = $sum ;   
                    }
                }
  
            }

        
        }
        return $nearNumber;
    }