每日一道Leetcode - 658. 找到 K 个最接近的元素 【二分查找】

在这里插入图片描述

class Solution {
    
    
    public List<Integer> findClosestElements(int[] arr, int k, int x) {
    
    
        List<Integer> ans = Arrays.stream(arr).boxed().collect(Collectors.toList());
        int n = ans.size();
        // 如果x值小于第一个值,则直接返回前k个
        if(x<=ans.get(0)){
    
    
            return ans.subList(0,k);
        }else if(x>=ans.get(n-1)){
    
    
            return ans.subList(n-k,n);
        }else{
    
    
            // 否则就在中间找,使用二分查找法
            // Collections.binarySearch 使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序。
            // binarysearch在指定数组中查找指定值的索引值,该值在范围内找得到则返回该值的索引值,找不到则返回该值的插入位置,如果该值大于指定范围最大值则返回-(maxlength+1)
            int index = Collections.binarySearch(ans,x);
            // 需要在index的左右各k个位置找到需要最近的值
            if(index<0){
    
    
                index = -index - 1;
            }
            // 找两个边界
            int low = Math.max(0,index-k-1);
            int high = Math.min(ans.size()-1,index+k-1);
            // 缩小区间使得只有k个值
            while(high-low+1>k){
    
    
                if((x-ans.get(low))<=(ans.get(high)-x)){
    
    
                    high--;
                }else if((x-ans.get(low))>(ans.get(high)-x)){
    
    
                    low++;
                }
            }
            return ans.subList(low,high+1);
        }

    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41041275/article/details/112463439