问题描述:
给定一个排序好的数组,两个整数 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]
补充示例3:
输入: [0,1,11,2,3,6,7,8,9], k=9, x=4
输出: [0,1,11,2,3,6,7,8]
原因:左侧的数字比右侧的数字更接近4,所以,左侧数字多。
说明:
k 的值为正数,且总是小于给定排序数组的长度。
数组不为空,且长度不超过 104
数组里的每个元素与 x 的绝对值不超过 104
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-k-closest-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
执行结果:
代码描述:
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
// 注释掉的部分,想先处理特殊情况,但是有越界,又找不出哪里越界,先摆上
// 如果有热心网友发现,欢迎留言指出。
/*
vector<int> res;
if(arr.size() == 0) return res; // arr 没有数据
if(arr.size() <= k) return arr; // arr 的数据不够k个
if(arr[0] >= x && arr.size() > k) // arr 的第一个比x还小
{
for(int i = 0; i < k; ++i)
{
res.push_back(arr[i]);
}
return res;
}
if(arr[arr.size() - 1] <= x && arr.size() > k) // arr的最后一个比 x 还大
{
int num;
num = arr.size() - k - 1;
for(int i = num; i < arr.size(); ++num)
{
res.push_back(arr[num]);
}
return res;
}
*/
int left = 0;
int right = arr.size() - k;// 保证右侧剩下的够k个数
while(left < right)
{
int mid = (right + left)/2;
if(x-arr[mid] > arr[mid + k] - x) // 用K个数的两端,进行比较,高效
{
left = mid + 1;
}
else
{
right = mid;
}
}
return vector<int>(arr.begin()+left, arr.begin()+k+left); // 迭代器处理,更高效
}
};