0
点赞
收藏
分享

微信扫一扫

找到K个最接近的元素-滑窗、二分

圣杰 2022-05-23 阅读 79


找到K个最接近的元素-滑窗、二分_ide

二分法:左闭右开

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);
}
};



举报

相关推荐

0 条评论