https://leetcode-cn.com/problems/find-k-closest-elements/description/
给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x
的差值一样,优先选择数值较小的那个数。
示例 1:
输入: [1,2,3,4,5], k=4, x=3
输出: [1,2,3,4]
示例 2:
输入: [1,2,3,4,5], k=4, x=-1
输出: [1,2,3,4]
说明:
k 的值为正数,且总是小于给定排序数组的长度。
数组不为空,且长度不超过 10^4
数组里的每个元素与 x 的绝对值不超过 10^4
int* findClosestElements(int* arr, int arrSize, int k, int x, int* returnSize){
// 先搜索插入位置(35题的搜索位置)
int low = 0, high = arrSize - 1;
int xindex = -1;
while(low <= high){
int mid = low + ((high - low)>>1);
if (arr[mid] >= x){
if(mid == 0 || arr[mid-1] < x){
xindex = mid;
break;
}
high = mid - 1;
}else{
low = mid + 1;
}
}
if(xindex==-1){
xindex = arrSize;
}
int *res = (int*)malloc(k*sizeof(int));
*returnSize = k;
// 利用双指针判断加入哪些元素
int l = xindex-1, r = xindex;
while(l>=0 && r<=arrSize-1 && r-l-1<k){
if(x-arr[l]<=arr[r]-x){
l--;
}else{
r++;
}
}
int tmp = k-(r-l-1);
if(tmp > 0){
if(l<0){
r += tmp;
}else{
l -= tmp;
}
}
memcpy(res, arr+l+1, sizeof(int)*k);
return res;
}
别人的代码,简洁、速度也不慢。排除法+双指针 不断压缩所求的区间,也即这里的方法一
int* findClosestElements(int* arr, int arrSize, int k, int x, int* returnSize){
*returnSize = k;
int left = 0;
int right = arrSize - 1;
while (right - left >= k) {
if (x*2 <= arr[right] + arr[left]) {
right--;
} else {
left++;
}
}
return &arr[left];
}