zoukankan      html  css  js  c++  java
  • [LeetCode] 658. Find K Closest Elements

    Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.

    Example 1:

    Input: arr = [1,2,3,4,5], k = 4, x = 3
    Output: [1,2,3,4]
    

    Example 2:

    Input: arr = [1,2,3,4,5], k = 4, x = -1
    Output: [1,2,3,4]

    Constraints:

    • 1 <= k <= arr.length
    • 1 <= arr.length <= 10^4
    • Absolute value of elements in the array and x will not exceed 104

    找到K个最接近的元素。

    给定一个排序好的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。

    整数 a 比整数 b 更接近 x 需要满足:

    |a - x| < |b - x| 或者
    |a - x| == |b - x| 且 a < b

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-k-closest-elements
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    最优解是二分法。因为 input 数组是有序的而且找的数字一定是在数组中,所以可以用二分法。这个题虽然找的是一个区间(若干个数字),但是由于要找的数字的个数是确定的,所以如果找到了区间的左边界,也就等同于找到了整个区间。这一点很像34题

    关于这个要找的左边界,他的范围是[0, nums.length - K),注意是左闭右开的区间。代码第四行的 right 是在数组下标范围外的。每当找到一个 mid 数字的时候,比较的是 nums[mid] 和 nums[mid + K] 谁与X的差值更小,以决定二分法到底是往左还是往右。这里我们判断的时候不需要添加绝对值符号。我这里分享一个写的很好的帖子说明为什么不需要加绝对值符号。

    时间O(logn)

    空间O(k) - output array

    Java实现

     1 class Solution {
     2     public List<Integer> findClosestElements(int[] arr, int k, int x) {
     3         int left = 0;
     4         int right = arr.length - k;
     5         while (left < right) {
     6             int mid = left + (right - left) / 2;
     7             if (x - arr[mid] > arr[mid + k] - x) {
     8                 left = mid + 1;
     9             } else {
    10                 right = mid;
    11             }
    12         }
    13         List<Integer> res = new ArrayList<>();
    14         for (int i = left; i < left + k; i++) {
    15             res.add(arr[i]);
    16         }
    17         return res;
    18     }
    19 }

    这里我再补充一个很巧妙的双指针的做法。我参考了这个帖子。这个思路很好地利用了 input 数组是排序的条件,同时写起来也不是很难。

    时间O(n) - worse case

    空间O(k) - output

    Java实现

     1 class Solution {
     2     public List<Integer> findClosestElements(int[] arr, int k, int x) {
     3         int left = 0;
     4         int right = arr.length - 1;
     5         while (left + k <= right) {
     6             if (Math.abs(arr[left] - x) > Math.abs(arr[right] - x)) {
     7                 left++;
     8             } else {
     9                 right--;
    10             }
    11         }
    12         List<Integer> res = new ArrayList<>();
    13         for (int i = left; i < left + k; i++) {
    14             res.add(arr[i]);
    15         }
    16         return res;
    17     }
    18 }

    相关题目

    34. Find First and Last Position of Element in Sorted Array

    658. Find K Closest Elements

    LeetCode 题目总结

  • 相关阅读:
    代码演示C#各版本新功能
    【转】Spring Security Authentication (认证)
    maven groupId分组名称,artifactId项目名称
    【转】Maven的本地仓库和镜像源配置
    【转】asp.net core环境变量详解
    【转】建议收藏备用:.net core使用QRCoder生成普通二维码和带Logo的二维码详细使用教程,源码已更新至开源模板
    【转】VS中添加自定义代码片段
    【转】Java JDK和IntelliJ IDEA 配置及安装
    Download .NET Core
    站点部署,IIS配置优化指南[转]
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13138763.html
Copyright © 2011-2022 走看看