【Leetcode】658. Find K Closest Elements

题目地址:

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

在一个长 n n n的升序数组 A A A中(不一定严格升序),返回距离某数 x x x最近的 k k k个数。数据保证数组长度大于 k k k

思路是二分。我们可以对这 k k k个数的左端点的下标做二分。若数组长度为 l l l,那么这个左端点的范围就是 [ 0 , l − k ] [0, l-k] [0,lk]。对于每个分点 m m m,我们考虑 x − A [ m ] x-A[m] xA[m] A [ m + k ] − x A[m+k]-x A[m+k]x哪个小,如果前者小或者一样小,那么向右找只能找到更差的解,但是注意到题目要求如果有一样近的则取较小的,所以如果两个一样小,说明 x x x正好夹在两个端点正中间,当前所选的区间有可能是最终解,所以移动范围的右端点到 m m m,否则移动范围的左端点到 m + 1 m+1 m+1。如此这般,直到分出结果。代码如下:

class Solution {
 public:
  vector<int> findClosestElements(vector<int>& a, int k, int x) {
    vector<int> res;
    int l = 0, r = a.size() - k;
    while (l < r) {
      int mid = l + (r - l >> 1);
      if (x - a[mid] <= a[mid + k] - x) r = mid;
      else l = mid + 1;
    }

    return vector<int>(a.begin() + l, a.begin() + l + k);
  }
};

时间复杂度 O ( log ⁡ ( n − k ) + k ) O(\log (n-k)+k) O(log(nk)+k) n n n是数组长度,空间 O ( 1 ) O(1) O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值