Skip to content
JZLeetCode
Go back

LeetCode 658 LintCode 460 Find K Closest Elements

Updated:

Table of contents

Open Table of contents

Description

Question links: leet 658, lint 460

Given a sorted integer array arr, two integers k and x, return the k closest integers to x in the array. The result should also be sorted in ascending order.

An integer a is closer to x than an integer b if:

Example 1:

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

Example 2:

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

Constraints:

Idea

The array is already sorted. We could binary search for the left boundary for the result section.

In the binary search, we compare x-arr[mid] and arr[mid+k]-x.

  1. If x-arr[mid] is smaller, x could be in between arr[mid] and arr[mid+k] or smaller than arr[mid]. We need to search on the left.
  2. Otherwise, x could be in between or bigger than arr[mid+k]. We need to search on the right.

Complexity: Time O(lognk)O(\log{n-k}), Space O(1)O(1).

Python

class Solution:
    """0 ms, 18.95 mb. @lee215"""

    def findClosestElements(self, arr: list[int], k: int, x: int) -> list[int]:
        l, r = 0, len(arr) - k
        while l < r:
            mid = l + (r - l) // 2
            if x - arr[mid] > arr[mid + k] - x:
                l = mid + 1
            else:
                r = mid
        return arr[l:l + k]

Java

public static List<Integer> findClosestElements(int[] arr, int k, int x) {
    int l = 0, r = arr.length - k;
    while (l < r) {
        int mid = l + (r - l) / 2;
        if (x - arr[mid] > arr[mid + k] - x) l = mid + 1;
        else r = mid;
    }
    List<Integer> res = new ArrayList<>(k);
    for (int i = l; i < l + k; i++) res.add(arr[i]);
    return res;
}

C++

vector<int> findClosestElements(vector<int> &arr, int k, int x) {
    int l = 0, r = (int) arr.size() - k;
    while (l < r) {
        int mid = l + (r - l) / 2;
        if (x - arr[mid] > arr[mid + k] - x) l = mid + 1;
        else r = mid;
    }
    return vector<int>(arr.begin() + l, arr.begin() + l + k);
}

Rust

pub fn find_closest_elements(arr: Vec<i32>, k: i32, x: i32) -> Vec<i32> {
    let k = k as usize;
    let (mut l, mut r) = (0usize, arr.len() - k);
    while l < r {
        let mid = l + (r - l) / 2;
        if x - arr[mid] > arr[mid + k] - x {
            l = mid + 1;
        } else {
            r = mid;
        }
    }
    arr[l..l + k].to_vec()
}
Share this post on:

Previous Post
LeetCode 862 LintCode 1507 Shortest Subarray with Sum at Least K
Next Post
LeetCode 1346 Check If N and Its Double Exist