Find K Closest Elements

Updated on 27 May, 2025
Find K Closest Elements header image

Problem Statement

The challenge is to find the k numbers closest to x from a given sorted integer array arr. The result should also maintain ascending order. A number a from the array is considered closer to x than another number b if:

  • The absolute difference between a and x is less than that between b and x, or
  • Both have the same absolute difference with x, but a is numerically less than b.

The function will return the k closest elements to x in a sorted array, always ensuring that the output is also sorted.

Examples

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

  • 1 <= k <= arr.length
  • 1 <= arr.length <= 104
  • arr is sorted in ascending order.
  • -104 <= arr[i], x <= 104

Approach and Intuition

Given that the array is already sorted, we can leverage this property for an efficient solution. Here's a structured approach to solving the problem:

  1. Binary Search for Efficient Positioning: Use binary search to find the closest element to x. This gives us a starting point.

  2. Two-pointer Technique:

    • Once the closest index is identified, use two pointers to find the closest k elements.
    • Initiate one pointer (left) at the found position and another (right) just after the found position.
  3. Compare and Collect:

    • Compare elements on the left and right of the found position to decide which one is closer to x.
    • Move the respective pointer (leftwards or rightwards) and collect the closest elements until you gather k elements.
  4. Edge Case Handling:

    • Handle the edge cases when pointers exceed array boundaries.
  5. Sorting the Result:

    • Even though the collected elements are closest to x, they may not be in ascending order due to the bidirectional collection.
    • Sort the gathered elements before returning them to ensure they are in ascending order as required by the problem statement.

By using binary search, the algorithm efficiently reduces the problem size by focusing only on the likely candidates around x, and the two-pointer approach helps in comparing the absolute differences to make optimal choices regarding which elements to include in the result.

Solutions

  • Java
  • Python
java
class Solution {
    public List<Integer> findKClosestElements(int[] numbers, int count, int target) {
        int start = 0;
        int end = numbers.length - count;

        while (start < end) {
            int center = (start + end) / 2;
            if (target - numbers[center] > numbers[center + count] - target) {
                start = center + 1;
            } else {
                end = center;
            }
        }

        List<Integer> closestElements = new ArrayList<Integer>();
        for (int index = start; index < start + count; index++) {
            closestElements.add(numbers[index]);
        }

        return closestElements;
    }
}

In this Java-based solution, you define a method to find the k closest elements to a given target from a sorted array of integers. The approach used here is efficiently based on a binary search to minimize the time complexity, typically optimizing it to O(log(N-k) + k), where N is the total number of elements in the input array.

The function findKClosestElements takes three parameters:

  • numbers: The sorted array of integers.
  • count: The number k representing how many closest elements to find.
  • target: The target number to which the closest elements are sought.

The implementation initiates by determining the plausible search space using two pointers, start and end, where end is initialized as numbers.length - count to ensure the group of k elements stays within array bounds.

  • Employ a while loop running as long as start is less than end. The midpoint, center, between start and end is calculated.

  • Compare the absolute differences between the target and the elements at the positions center and center + count to decide the search direction. This helps in narrowing down the region where the closest elements would exist:

    • If the element at center is farther away from the target than the element at position center + count, move the start to center + 1.
    • Otherwise, adjust end to center.

Once the closest interval is localized, populate a list, closestElements, with count numbers from the array starting from the start position.

This method efficiently locates and returns the k closest integers to the target in the list, leveraging binary search for an optimal performance in scenarios where the input list is considerably large.

python
class Solution:
    def getClosestKElements(self, elements: List[int], count: int, target: int) -> List[int]:
        start = 0
        end = len(elements) - count

        while start < end:
            middle = (start + end) // 2
            if target - elements[middle] > elements[middle + count] - target:
                start = middle + 1
            else:
                end = middle

        return elements[start:start + count]

The Python solution detailed below addresses the task of fetching the k closest elements to a given target from a sorted array. This functionality is encapsulated within a class method, getClosestKElements, which utilizes a binary search approach to efficiently find the desired segment of the array.

  • Define a class Solution which contains the method getClosestKElements. This method takes three parameters:

    • elements: A list of sorted integers.
    • count: The number of closest integers to the target you need to find (k).
    • target: The target number you want to find the closest elements to.
  • Initialize two pointers, start and end. Set start to 0 and end to the difference between the number of elements and the count. This positions end such that the slice from start to start + count doesn't exceed the list boundaries.

  • Implement a binary search:

    • Calculate the middle index of the current window as (start + end) // 2.
    • Compare the difference between target and the element at middle, to the difference between the element at middle + count and target.
    • Adjust the start or end pointer based on which side of the middle point is closer to the target. Specifically, if the left side is farther from the target than the right side, shift the start to middle + 1; otherwise, update end to middle.
  • To complete the method, return the subarray starting from start and extending count elements.

This solution ensures that the calculation is both space and time-efficient, using binary search to minimize the iterations required to find the closest elements rather than scanning all possibilities. By aligning to the middle in each iteration, the algorithm effectively narrows down the range, concentrating on the part of the list most likely to contain the closest elements to the target.

Comments

No comments yet.