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.
Example 1:
Input: [1,2,3,4,5], k=4, x=3 Output: [1,2,3,4]
Example 2:
Input: [1,2,3,4,5], k=4, x=-1 Output: [1,2,3,4]
Note:
- The value k is positive and will always be smaller than the length of the sorted array.
- Length of the given array is positive and will not exceed 104
- Absolute value of elements in the array and x will not exceed 104
UPDATE (2017/9/19):
The arr parameter had been changed to an array of integers (instead of a list of integers). Please reload the code definition to get the latest changes.
Approach #1:
class Solution { public: vector<int> findClosestElements(vector<int>& arr, int k, int x) { int len = arr.size(); //cout << x << " " << k << endl; if (x <= arr[0]) return vector<int> (arr.begin(), arr.begin()+k); else if (x >= arr[len-1]) return vector<int> (arr.end()-k, arr.end()); else { int index = lower_bound(arr.begin(), arr.end(), x) - arr.begin(); int low = max(0, index - k - 1), high = min(len-1, index+k-1); while (high - low > k - 1) { if (low < 0 || (x - arr[low]) <= (arr[high] - x)) high--; else if (high > len-1 || (x - arr[low]) > (arr[high] - x)) low++; } return vector<int> (arr.begin()+low, arr.begin()+high+1); } } };
Runtime: 72 ms, faster than 98.40% of C++ online submissions for Find K Closest Elements.
Analysis:
The original array has been sorted so we can take this advantage by the following steps.
- If the target
x
is less or equal than the first element in the sorted array, the firstk
elements are the result. - Similarly, if the target
x
is more or equal than the last element in the sorted array, the lastk
elements are the result. - Otherwise, we can use binary search to find the
index
of the element, which is equal (when this list hasx
) or a little bit larger thanx
(when this list does not have it). Then setlow
to its leftk-1
position, andhigh
to the rightk-1
position of thisindex
as a start. The desired k numbers must in this rang [index-k-1, index+k-1]. So we can shrink this range to get the result using the following rules.- If
low
reaches the lowest index0
or thelow
element is closer tox
than thehigh
element, decrease thehigh
index. - If
high
reaches to the highest indexarr.size()-1
or it is nearer tox
than thelow
element, increase thelow
index. - The looping ends when there are exactly k elements in [low, high], the subList of which is the result.
- If
Complexity Analysis
-
Time complexity : O(log(n)+k)O(log(n)+k). O(log(n))O(log(n)) is for the time of binary search, while O(k)O(k) is for shrinking the index range to k elements.
-
Space complexity : O(k)O(k). It is to generate the required sublist.