跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Google 面试题:在排序数组中找最接近的 K 个数
未分類
10 9 月 2020

Google 面试题:在排序数组中找最接近的 K 个数

Google 面试题:在排序数组中找最接近的 K 个数

資深大佬 : zzzrf 1

给一个目标数 target, 一个非负整数 k, 一个按照升序排列的数组 A 。在 A 中找与 target 最接近的 k 个整数。返回这 k 个数并按照与 target 的接近程度从小到大排序,如果接近程度相当,那么小的数排在前面。

  1. k 是一个非负整数,并且总是小于已排序数组的长度。
  2. 给定数组的长度是正整数, 不会超过 10^4
  3. 数组中元素的绝对值不会超过 10^4

点此在线做题

样例 1:

输入: A = [1, 2, 3], target = 2, k = 3 输出: [2, 1, 3] 

样例 2:

输入: A = [1, 4, 6, 8], target = 3, k = 3 输出: [4, 1, 6] 

[题解]

直接在数组中二分查找 target, 如果不存在则返回大于 target 的最小的或者小于 target 的最大的元素均可. 然后使用两根指针从该位置开始向两端遍历, 每次把差值比较小的元素放入答案中然后将该指针向边界方向移动一下即可.

public class Solution {     /**      * @param A      an integer array      * @param target an integer      * @param k      a non-negative integer      * @return an integer array      */     public int[] kClosestNumbers(int[] A, int target, int k) {         int[] result = new int[k];          if (A == null || A.length == 0) {             return A;         }         if (k > A.length) {             return A;         }          int index = firstIndex(A, target);          int start = index - 1;         int end = index;         for (int i = 0; i < k; i++) {             if (start < 0) {                 result[i] = A[end++];             } else if (end >= A.length) {                 result[i] = A[start--];             } else {                 if (target - A[start] <= A[end] - target) {                     result[i] = A[start--];                 } else {                     result[i] = A[end++];                 }             }         }         return result;     }      private int firstIndex(int[] A, int target) {         int start = 0, end = A.length - 1;         while (start + 1 < end) {             int mid = start + (end - start) / 2;             if (A[mid] < target) {                 start = mid;             } else if (A[mid] > target) {                 end = mid;             } else {                 end = mid;             }         }          if (A[start] >= target) {             return start;         }         if (A[end] >= target) {             return end;         }         return A.length;     } } 

大佬有話說 (12)

  • 資深大佬 : zoyua

    这题感觉用堆比较好,节点的值是元素与 target 的差值,维护一个 k 大小的小根堆,最后依次弹出堆顶

  • 主 資深大佬 : zzzrf

    @zoyua 学习了~

  • 資深大佬 : widewing

    k 很大的情况下是不是有更高效的做法

  • 資深大佬 : xiadong1994

    @zoyua 时间复杂度太高

  • 主 資深大佬 : zzzrf

    @widewing 我目前只想到了这种解法,等个大佬

  • 資深大佬 : widewing

    找到 target,然后左右 取 k/2,比较大小,然后再 k/2 +/- k/4,这样二分下去,时间复杂度 log(k)

  • 資深大佬 : XiaoxiaoPu

    @zoyua 这道题有个信息「数组 A 」是升序排列的,用堆的话无法利用这一点,应该不是最佳方案。

  • 資深大佬 : binux

    @widewing K 个数最终是要被输出的,最小也是 O(k),你这样找边界没有意义。

  • 資深大佬 : widewing

    @binux 数组是排序的啊

  • 資深大佬 : georgetso

    @zoyua 题主复杂度 log(N) + k; 建堆复杂度超了.

  • 資深大佬 : binux

    @widewing 但是你要输出 K 个数的啊,你不访问 k 次怎么输出它呢?

  • 資深大佬 : widewing

    @binux 好吧,但至少节省了 k 个比较

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具