刚开始写这道题的时候,果断采用了暴力破解法,不出所料,跑到最后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的值
}