找到 K 个最接近的元素 --java记录

给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。
在这里插入图片描述
在这里插入图片描述
思路:二分法查找
1、利用二分法先找到中间值,left 或 right 值是 等于x,如果数组不存在x则 两个值最接近x。
2、将left 与right 值 与x 做差进行比较,小则left – ,大则right++ 。
3、最后left + 1 到 right -1 索引 赋值给list 。(至于最后索引下标为什么是这个可以话一个数组看一下)

class Solution {
     public List<Integer> findClosestElements(int[] arr, int k, int x) {
	ArrayList <Integer> list = new ArrayList<Integer>();
         if(arr.length == 1) {
             list.add(arr[0]);
             return list;
         } 
    int left = 0, right = arr.length - 1;
    int length = arr.length;
    int mid = -1;
    while (left + 1 < right){
        mid = (left + right) / 2;
        if (arr[mid] >= x){
            right = mid;
        }
        else{
            left = mid;
        }
    }
 //从left,right处寻找与x之差的绝对值较小者
    for (int i = 0; i < k; ++i){
        if (left >=0 && right < length){
            //取与x之差的绝对值较小者
            if ((x - arr[left]) <= (arr[right] - x)){
                left--;
            }
            else{
                right++;
            }
        }
        //否则取单边
        else if (left >=0){
        	left--;
        }
        else{
        	right++;
        }
    }
    for(int j = left + 1; j < right; j++){
    	 list.add(arr[j]);
    }
    return list;
 
	}
}

思路:
保留k个最近的数字,可以去掉最远的n-k个数。
观察数组 中与x最远的地方肯定是在数组两端,因此每次比较数组两端与x的差值,大的则去掉。直到数组还剩k个数字即为结果。

class Solution {
     public List<Integer> findClosestElements(int[] arr, int k, int x) {
		 	ArrayList <Integer> list = new ArrayList<Integer>();
 
	        int left = 0;
	        int right = arr.length - 1;
	        int length = arr.length - k;
	        while(length > 0) { //去掉相对较大的数字
	        	 if((x- arr[left]) > (arr[right] - x )) { //左边差值大于右边,左边索引 ++
	        		 left ++;
	        	 }else {
	        		 right --;
	        	 }
	        	 length --;
	        }
	        for(int i = left; i <= right; i++ ) {
	        	list.add(arr[i]);
	        }
	        return list;
 
	      
	        
	    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值