LeetCode - Find K Closest Elements

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]
Note:
The value k is positive and will always be smaller than the length of the sorted array.
Length of the given array is positive and will not exceed 104
Absolute value of elements in the array and x will not exceed 104
UPDATE (2017/9/19):
The arr parameter had been changed to an array of integers (instead of a list of integers). Please reload the code definition to get the latest changes.

中了 priorityqueue 的毒,自己写了个比较繁琐的方法:

class Solution {
    public List<Integer> findClosestElements(int[] arr, int k, int x) {
        if(arr == null || arr.length == 0){
            return new ArrayList<Integer>();
        }
        PriorityQueue<int[]> pq = new PriorityQueue<>((e1,e2) -> elementCompare(e1,e2));
        for(int a : arr){
            pq.add(new int[]{a,Math.abs(a-x)});
            if(pq.size() > k){
                pq.poll();
            }
        }
        List<Integer> list = new ArrayList<>();
        while(!pq.isEmpty()){
            list.add(pq.poll()[0]);
        }
        Collections.sort(list);
        return list;
    }
    private int elementCompare(int[] e1, int[]e2){
        if(e1[1] != e2[1]){
            return e2[1] - e1[1];
        }
        else{
            return e2[0] - e1[0];
        }
    }
}

更合适的方法:

用binary search + 双指针来做, 注意最后加入list中的顺序问题:

class Solution {
    public List<Integer> findClosestElements(int[] arr, int k, int x) {
        if(arr == null || arr.length == 0){
            return new ArrayList<Integer>();
        }
        List<Integer> list = new ArrayList<>();
        int len = arr.length;
        if(x >= arr[len-1]){
            for(int i = len - k; i<len; i++){
                list.add(arr[i]);
            }
        }
        else if(x <= arr[0]){
            for(int i = 0; i<k; i++){
                list.add(arr[i]);
            }
        }
        else{
            int n = 0;
            int l = 0;
            int h = len - 1;
            while(l <= h){
                int mid = l + (h-l)/2;
                if(arr[mid] == x || (arr[mid] > x && arr[mid-1] < x)){
                    n = mid;
                    break;
                }
                else if(arr[mid] > x){
                    
                    h = mid - 1;
                }
                else if(arr[mid] < x){
                    l = mid + 1;
                }
                
            }
            int less = n-1, more = n;
            while(less >= 0 && more < len && k > 0){
                if(Math.abs(arr[less] - x) <= Math.abs(arr[more] - x)){
                    list.add(0, arr[less]);
                    less -- ;
                }
                else{
                    list.add(arr[more]);
                    more ++;
                }
                k--;
            }
            while(less >= 0 && k > 0){
                list.add(0, arr[less--]);
                k--;
            }
            while(more < len && k > 0 ){
                list.add(arr[more++]);
                k--;
            } 
        }
        return list;
    }

}

猜你喜欢

转载自www.cnblogs.com/incrediblechangshuo/p/9698301.html
今日推荐