658. Find K Closest Elements

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;
    }
相關文章
相關標籤/搜索