BiruLyu
9/9/2017 - 11:04 PM

658. Find K Closest Elements(#).java

public List<Integer> findClosestElements(List<Integer> arr, int k, int x) {
     Collections.sort(arr, (a,b) -> a == b ? a - b : Math.abs(a-x) - Math.abs(b-x));
     arr = arr.subList(0, k);
     Collections.sort(arr);
     return arr;
}

public List<Integer> findClosestElements(List<Integer> arr, int k, int x) {
    int lo = 0, hi = arr.size() - k;
    while (lo < hi) {
        int mid = (lo + hi) / 2;
        if (x - arr.get(mid) > arr.get(mid+k) - x)
            lo = mid + 1;
        else
            hi = mid;
    }
    return arr.subList(lo, lo + k);
}
class Solution {
    private int ClosetElement (List<Integer> arr, int target) {
        int l = 0, r = arr.size() - 1;
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (arr.get(mid) == target) return mid;
            if (arr.get(mid) < target) {
                l = mid + 1;
            } else {
                r = mid;
            }
        }
        if (l > 0) {
            return Math.abs(arr.get(l - 1) - target) < Math.abs(arr.get(l) - target) ? l - 1 : l;
        } else {
            return l;
        }
    }
    public List<Integer> findClosestElements(List<Integer> arr, int k, int x) {
        int center = ClosetElement(arr, x);
        int low = Math.max(0, center - k + 1), high = Math.min(arr.size() - 1, center + k - 1);
        while (high - low > k - 1) {
            if (low < 0 || (x - arr.get(low) <= arr.get(high) - x)) {
                high--;
            } else if (high > arr.size() - 1 || (x - arr.get(low) > arr.get(high) - x)){
                low++;
            }
        }
        return arr.subList(low, high + 1);
    }
}