Solution 1 : Log n + k http://www.cnblogs.com/grandyang/p/7519466.html https://shineboy2013.github.io/2018/01/28/lee-658/ // correct class Solution { public List<Integer> findClosestElements(int[] arr, int k, int x) { List<Integer> res = new ArrayList<>(); int smallestLarger = binarySearch(arr, x); int left = smallestLarger - 1; for(int i = k; i > 0; i--){ if(left < 0){ res.add(arr[smallestLarger++]); }else if(smallestLarger >= arr.length){ res.add(arr[left--]); }else if(x - arr[left] <= arr[smallestLarger] - x){ res.add(arr[left--]); }else{ res.add(arr[smallestLarger++]); } } Collections.sort(res); return res; } private int binarySearch(int[] arr, int x){ int left = 0; int right = arr.length - 1; while(left <= right){ int mid = left + (right - left) / 2; if(arr[mid] == x){ left = mid + 1; }else if(arr[mid] < x){ left = mid + 1; }else{ right = mid - 1; } } return left; } }
sol 2 html
I binary-search for where the resulting elements start in the array. It's the first index i
so that arr[i]
is better than arr[i+k]
(with "better" meaning closer to or equally close to x
). Then I just return the k
elements starting there.git
Explanation: Assume we are taking A[i] ~ A[i + k -1]. We can binary research i We compare the distance between x - A[mid] and A[mid - k] - x If x - A[mid] > A[mid + k] - x, it means A[mid + 1] ~ A[mid + k] is better than A[mid] ~ A[mid + k - 1], and we have mid smaller than the right i. So assign left = mid + 1. Reversely, it's similar. Time Complexity: O(log(N - K)) It's funny that when K increases, the time complexity decrease instead. Java: public List<Integer> findClosestElements(int[] A, int k, int x) { int left = 0, right = A.length - k; while (left < right) { int mid = (left + right) / 2; if (x - A[mid] > A[mid + k] - x) left = mid + 1; else right = mid; } List<Integer> res = new ArrayList<>(); for (int i = 0; i < k; i++) res.add(A[left + i]); return res; }