思路
二分查找。首先二分查找到最后一个<=target的位置,并将left设置为该位置,right为该位置+1,然后根据left和right与target的差值得到left和right指针移动的条件(left和right指针都指向下一个位置,可以从k的初始化看出来)。最后将[left+1, right-1]内的元素依次存入arraylist即可。
时间复杂度O(logn+k)
空间复杂度O(1)
注意:lintcode460与本题唯一不同的是输出不需要排序
代码
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
int left = findLowerClosest(arr, x);int right = left + 1;List<Integer> res = new ArrayList<>();for (int i = 0; i < k; i++) {
if (isLeftCloser(arr, x, left, right)) {
left--;} else {
right++;}}for (int i = left + 1; i < right; i++) {
res.add(arr[i]);}return res;}private boolean isLeftCloser(int[] arr, int target, int left, int right) {
if (left < 0) {
return false;}if (right >= arr.length) {
return true;}if (target - arr[left] != arr[right] - target) {
return target - arr[left] < arr[right] - target;}return true;}private int findLowerClosest(int[] arr, int x) {
int start = 0, end = arr.length - 1;while (start + 1 < end) {
int mid = start + (end - start) / 2;if (arr[mid] == x) {
start = mid;} else if (arr[mid] < x) {
start = mid;} else {
end = mid;}}if (arr[end] <= x) {
return end;}if (arr[start] <= x) {
return start;}return 0; }
}