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
class Solution {
public List<Integer> findClosestElements(List<Integer> arr, int k, int x) {
if (x <= arr.get(0))
return arr.subList(0, k);
if (x >= arr.get(arr.size() - 1))
return arr.subList(arr.size() - k, arr.size());
LinkedList<Integer> re = new LinkedList<>();
int lo = 0;
int hi = arr.size() - 1;
int i = -1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (arr.get(mid) == x) {
i = mid;
break;
} else if (arr.get(mid) < x)
lo = mid + 1;
else
hi = mid - 1;
}
if (i == -1) {
int lo_gap = Math.abs(arr.get(lo) - x);
int hi_gap = Math.abs(arr.get(hi) - x);
i = lo_gap > hi_gap ? hi : lo;
}
re.add(arr.get(i));
lo = i - 1;
hi = i + 1;
while (--k > 0) {
int lo_gap = Integer.MAX_VALUE;
int hi_gap = Integer.MAX_VALUE;
if (lo >= 0)
lo_gap = Math.abs(arr.get(lo) - x);
if (hi < arr.size())
hi_gap = Math.abs(arr.get(hi) - x);
if (lo_gap <= hi_gap) {
re.addFirst(arr.get(lo));
lo--;
} else {
re.addLast(arr.get(hi));
hi++;
}
}
return re;
}
}