658. Find K Closest Elements

找出最接近x的k个数。

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]

这题我代码写得太长了,时间是O(n)。我看到一种新颖的解法:

public List findClosestElements(List 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);
}

我的代码:

    public List findClosestElements(List arr, int k, int x) {
        //首先利用二分找到x所在的index,或者最接近x的index
        //然后向左右分别搜寻k或者k-1个
        if (arr == null || arr.size() == 0) return null;
        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());
        int start = 0;
        int end = arr.size() - 1;
        int pivot = -1;
        while (start <= end) {
            int mid = start + (end - start) / 2;
            if (arr.get(mid) == x) {
                pivot = mid;
                break;
            }
            if (arr.get(mid) < x) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        //如果没找到相同的数字
        if (start > end) {
            if (distanceToX(start, x, arr) < distanceToX(end, x, arr)) {
                pivot = start;
            } else
                pivot = end;
        }
        List res = new ArrayList<>();
        int left = pivot - 1, right = pivot + 1;
        int count = k;
        while (count > 1) {
            if (count == k)
                res.add(arr.get(pivot));
            if (distanceToX(left, x, arr) <= distanceToX(right, x, arr)) {
                res.add(0, arr.get(left));
                left--;
            } else {
                res.add(arr.get(right));
                right++;
            }
            count--;
        }
        return res;
    }

    private int distanceToX(int idx, int x, List arr) {
        if (idx < 0 || idx >= arr.size()) {
            return Integer.MAX_VALUE;
        }
        return Math.abs(arr.get(idx) - x);
    }

你可能感兴趣的:(658. Find K Closest Elements)