二分法:左闭右开
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
int left = 0;
int right = arr.size() - k;
while(left < right){
int mid = left + (right - left) / 2;
if(x - arr[mid] <= arr[mid + k] - x){
right = mid;
}
else{
left = mid + 1;
}
}
return vector<int>(arr.begin() + left, arr.begin() + left + k);
}
};
二分法:闭区间
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
int left = 0;
int right = arr.size() - k - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(x - arr[mid] > arr[mid + k] - x){
left = mid + 1;
}
else{
right = mid - 1;
}
}
return vector<int>(arr.begin() + left, arr.begin() + left + k);
}
};
从两边删除元素
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
list<int> num(arr.begin(), arr.end());
while(num.size() > k){
if(abs(num.front() - x) > abs(num.back() - x)){
num.pop_front();
}
else{
num.pop_back();
}
}
return vector<int>(num.begin(), num.end());
}
};
// Delete the the farther one of leftmost side and rightmost side element until k left
class Solution2 {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
auto res = arr;
while (res.size() > k) {
if (x - res.front() > res.back() - x) {
res.erase(res.begin());
} else {
res.pop_back();
}
}
return res;
}
};
滑窗:
// Sliding window
class Solution1 {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
int minDelta = INT_MAX;
int delta = 0;
int startIdx = 0;
for (int i = 0; i < k; i++) {
delta += abs(arr[i] - x);
}
minDelta = min(delta, minDelta);
for (int i = k; i < arr.size(); i++) {
delta -= abs(arr[i - k] - x);
delta += abs(arr[i] - x);
if (delta < minDelta) {
minDelta = delta;
startIdx = i - k + 1;
}
}
return vector<int>(arr.begin() + startIdx, arr.begin() + startIdx + k);
}
};