leetcode 658.找到-k-个最接近的元素(find k closest elements)C语言

leetcode 658.找到-k-个最接近的元素(find k closest elements)C语言

1.description

https://leetcode-cn.com/problems/find-k-closest-elements/description/

给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x
的差值一样,优先选择数值较小的那个数。

示例 1:

输入: [1,2,3,4,5], k=4, x=3
输出: [1,2,3,4]

示例 2:

输入: [1,2,3,4,5], k=4, x=-1
输出: [1,2,3,4]

说明:

k 的值为正数,且总是小于给定排序数组的长度。
数组不为空,且长度不超过 10^4
数组里的每个元素与 x 的绝对值不超过 10^4

2.solution

int* findClosestElements(int* arr, int arrSize, int k, int x, int* returnSize){
    // 先搜索插入位置(35题的搜索位置)
    int low = 0, high = arrSize - 1;
    int xindex = -1;

    while(low <= high){
        int mid = low + ((high - low)>>1);
        if (arr[mid] >= x){
            if(mid == 0 || arr[mid-1] < x){
                xindex = mid;
                break;
            }
            high = mid - 1;
        }else{
            low = mid + 1;
        }
    }

    if(xindex==-1){
        xindex = arrSize;
    }

    int *res = (int*)malloc(k*sizeof(int));
    *returnSize = k;

    // 利用双指针判断加入哪些元素
    int l = xindex-1, r = xindex;

    while(l>=0 && r<=arrSize-1 && r-l-1<k){
        if(x-arr[l]<=arr[r]-x){
            l--;
        }else{
            r++;
        }
    }

    int tmp = k-(r-l-1);
    if(tmp > 0){
        if(l<0){
            r += tmp;
        }else{
            l -= tmp;
        }
    }

    memcpy(res, arr+l+1, sizeof(int)*k);

    return res;
}

别人的代码,简洁、速度也不慢。排除法+双指针 不断压缩所求的区间,也即这里的方法一

int* findClosestElements(int* arr, int arrSize, int k, int x, int* returnSize){
    *returnSize = k;
    int left = 0;
    int right = arrSize - 1;
    while (right - left >= k) {
        if (x*2 <= arr[right] + arr[left]) {
            right--;
        } else {
            left++;
        }
    }
    return &arr[left];
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值