Given a sorted array, two integers k
and x
, find the k
closest elements to x
in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.
Example 1:
Input: [1,2,3,4,5], k=4, x=3 Output: [1,2,3,4]
Example 2:
Input: [1,2,3,4,5], k=4, x=-1 Output: [1,2,3,4]
题目要求很明确,就是要找一个排序序列中离目标值x最近的k个值,如果存在相同距离的值,则优先选择小的数值。
思路:由于是排序序列,不难想到使用二分查找,先查找到目标元素的位置,然后再以目标元素(如果不存在,则以最近的那个元素)为中心找k个值。
算法复杂度:O(logN)+O(k)
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
if (arr.empty())
return arr;
int len = arr.size();
int pos = binarySearch(arr, x, 0, len-1);//找到不小于k的位置
int l = pos-1; //记录左侧位置
int r = pos; //记录右侧位置
while(k--)
{
if (l>=0 && r<len) //均在有效范围内
{
if(x-arr[l] <= arr[r]-x)
{
l--;
}
else
{
r++;
}
}
else if (l<0)
{
r++;
}
else if (r>=len)
{
l--;
}
}
l = l+1; //跳出循环的时候,l进行了--操作,需要加回来
r = r-1; //跳出循环的时候r进行了++操作,需要减掉
vector<int> vec(arr.begin()+l, arr.begin()+r+1); //注意vector容器的第二个迭代器指向有效值的下一个位置
return vec;
}
int binarySearch(const vector<int> &vec, int k, int l, int r)
{
if (l>=r)
return l;
int mid = l+(r-l)/2;
if (vec[mid] < k)
{
return binarySearch(vec, k, mid+1, r);
}
else
{
return binarySearch(vec, k, l, mid);
}
}