Given a sorted integer array arr, two integers x and k, find the k closest elements to x in the array. The result should be sorted in ascending order by the absolute difference between each element and x. If there is a tie, the smaller elements are preferred.
Table of Contents
Example:
Input:
arr = [1, 2, 3, 4, 5]
x = 3
k = 3
Output:
[2, 3, 4]
Explanation: In the input array, the absolute differences between each element and x are [2, 1, 0, 1, 2]. The closest k=3 elements to x=3 are [2, 3, 4].
Solution in C++:
#include <iostream>
#include <vector>
#include <algorithm>
// Function to find k closest elements to x in the sorted array
std::vector<int> findClosestElements(std::vector<int>& arr, int k, int x) {
int left = 0;
int right = arr.size() - k;
// Use binary search to find the leftmost index of the k closest elements
while (left < right) {
int mid = left + (right - left) / 2;
// If the absolute difference between x and arr[mid] is greater or equal to
// the absolute difference between x and arr[mid+k], move the left pointer to mid+1
if (std::abs(x - arr[mid]) >= std::abs(x - arr[mid + k])) {
left = mid + 1;
} else {
right = mid;
}
}
// Return the k closest elements using the leftmost index found by binary search
return std::vector<int>(arr.begin() + left, arr.begin() + left + k);
}
int main() {
std::vector<int> arr = {1, 2, 3, 4, 5};
int x = 3;
int k = 3;
std::vector<int> result = findClosestElements(arr, k, x);
std::cout << "The " << k << " closest elements to " << x << " are: ";
for (int num : result) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
Explanation:
- The
findClosestElementsfunction takes a reference to a sorted vector of integersarr, an integerk, and an integerx. - We use a binary search approach to find the leftmost index of the k closest elements. To do this, we initialize the
leftpointer to 0 and therightpointer toarr.size() - k, representing the valid range of starting indices for the k closest elements. - In each iteration of the binary search, we calculate the midpoint
midbetweenleftandright, and compare the absolute difference betweenxandarr[mid]with the absolute difference betweenxandarr[mid + k]. If the former is greater or equal, it means that themidelement is farther away fromxcompared to the element atmid + k. In this case, we move theleftpointer tomid + 1. Otherwise, we update therightpointer tomid, as the leftmost index of the k closest elements must be before or equal tomid. - After the binary search, the
leftpointer points to the leftmost index of the k closest elements. We create a new vector using theleftpointer and copy the k closest elements from the original arrayarrto the new vector.
Time Complexity:
The time complexity of this solution is O(log(n-k) + k), where n is the number of elements in the input array arr. The binary search takes O(log(n-k)) time, and copying the k closest elements to the new vector takes O(k) time.
Space Complexity:
The space complexity of this solution is O(k), where k is the number of elements to be returned in the output vector. This is because we create a new vector to store the k closest elements.