LeetCode 16.最接近的三数之和

81 阅读2分钟

力扣16题.png

刚开始写这道题的时候,果断采用了暴力破解法,不出所料,跑到最后2个测试用例时超时了,这里应该是专门拿来卡暴力破解法的。这里的解法用的是排序+双指针法:可以先将数组变的有序,再遍历一个值,另外2个值可以从取的这个值开始采用双指针进行筛选(有序)。

//插入排序法
void insertionSort(int* arr, int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];  // 当前元素
        int j = i - 1;

        // 将所有大于key的元素移动到右侧
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }

        // 将key放到正确的位置
        arr[j + 1] = key;
    }
}
int threeSumClosest(int* nums, int numsSize, int target) {
    if(numsSize==3)//如果就3个数则直接返回
    {
        return nums[0]+nums[1]+nums[2];
    }
   int min=abs(nums[0]+nums[1]+nums[2]-target);//设置绝对最小值,记录每次第一个指正i移动时,相对最小值
   int sumMin=nums[0]+nums[1]+nums[2];//定义要返回的最接近target的数
   insertionSort(nums,numsSize);//排序
   for(int i=0;i<numsSize;i++)
   {
    if (i > 0 && nums[i] == nums[i - 1]) {//如果当前数值与前一个相同则直接跳过
            continue;
        }
    int l=i+1;int r=numsSize-1;
    
    while(l<r)
    {
        if(nums[i]+nums[l]+nums[r]==target)//等于target肯定是最接近的,直接返回即可
    {
        return target;
    }
        if(abs(nums[i]+nums[l]+nums[r]-target)<=min)//开始比较是否比之前的相对最小值更加接近target
    {
        min=abs(nums[i]+nums[l]+nums[r]-target);
        sumMin=nums[i]+nums[l]+nums[r];
    }
    if(nums[i]+nums[l]+nums[r]<target)//小于就让左边界扩大
    {
        l++;
    }
    
    if(nums[i]+nums[l]+nums[r]>target)//大于就让右边界缩小
    {
        r--;
    }
    //依次让数组中的每个元素充当一次“第一次选择的数字”
    }
    
   }
   return sumMin;//最后返回最接近target的值
}