I run across this problem:
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.
For example, given [1,2,3,4,5], k=4, x=3, we should have [1,2,3,4]. There is one solution using binary search:
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);
}
I couldn't understand if (x - arr[mid] <= arr[mid+k] - x) part and I try to explain this using precondition, invariant, and postcondition like we do with the
simple binary search problem. But, I have no clue what's the invariant in this case and how we prove the invariant holds through the loop execution. I also follow the article from topcoder but that doesn't help.
My attempt for the invariant: the index of the first number that is among the k closest values for the given target is in [left, right]. However, I cannot fully convince myself this is correct and actually holds during the loop.
If this question belongs to stackoverflow, let me know and I'll post it there instead.
Thanks in advance.