Open In App
Related Articles

Find k closest elements to a given value

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

Given a sorted array arr[] and a value X, find the k closest elements to X in arr[]. 

Examples: 

Input: K = 4, X = 35
arr[] = {12, 16, 22, 30, 35, 39, 42,
45, 48, 50, 53, 55, 56}
Output: 30 39 42 45

Note that if the element is present in array, then it should not be in output, only the other closest elements are required.

Recommended Practice

In the following solutions, it is assumed that all elements of array are distinct.

A simple solution is to do linear search for k closest elements. 

  1. Start from the first element and search for the crossover point (The point before which elements are smaller than or equal to X and after which elements are greater). This step takes O(n) time. 
  2. Once we find the crossover point, we can compare elements on both sides of crossover point to print k closest elements. This step takes O(k) time.

The time complexity of the above solution is O(n).

An Optimized Solution is to find k elements in O(Logn + k) time. The idea is to use Binary Search to find the crossover point. Once we find index of crossover point, we can print k closest elements in O(k) time.  

C++

#include<stdio.h>
 
/* Function to find the cross over point (the point before
which elements are smaller than or equal to x and after
which greater than x)*/
int findCrossOver(int arr[], int low, int high, int x)
{
// Base cases
if (arr[high] <= x) // x is greater than all
    return high;
if (arr[low] > x) // x is smaller than all
    return low;
 
// Find the middle point
int mid = (low + high)/2; /* low + (high - low)/2 */
 
/* If x is same as middle element, then return mid */
if (arr[mid] <= x && arr[mid+1] > x)
    return mid;
 
/* If x is greater than arr[mid], then either arr[mid + 1]
    is ceiling of x or ceiling lies in arr[mid+1...high] */
if(arr[mid] < x)
    return findCrossOver(arr, mid+1, high, x);
 
return findCrossOver(arr, low, mid - 1, x);
}
 
// This function prints k closest elements to x in arr[].
// n is the number of elements in arr[]
void printKclosest(int arr[], int x, int k, int n)
{
    // Find the crossover point
    int l = findCrossOver(arr, 0, n-1, x);
    int r = l+1; // Right index to search
    int count = 0; // To keep track of count of elements already printed
 
    // If x is present in arr[], then reduce left index
    // Assumption: all elements in arr[] are distinct
    if (arr[l] == x) l--;
 
    // Compare elements on left and right of crossover
    // point to find the k closest elements
    while (l >= 0 && r < n && count < k)
    {
        if (x - arr[l] < arr[r] - x)
            printf("%d ", arr[l--]);
        else
            printf("%d ", arr[r++]);
        count++;
    }
 
    // If there are no more elements on right side, then
    // print left elements
    while (count < k && l >= 0)
        printf("%d ", arr[l--]), count++;
 
    // If there are no more elements on left side, then
    // print right elements
    while (count < k && r < n)
        printf("%d ", arr[r++]), count++;
}
 
/* Driver program to check above functions */
int main()
{
int arr[] ={12, 16, 22, 30, 35, 39, 42,
            45, 48, 50, 53, 55, 56};
int n = sizeof(arr)/sizeof(arr[0]);
int x = 35, k = 4;
printKclosest(arr, x, 4, n);
return 0;
}

                    

Java

// Java program to find k closest elements to a given value
class KClosest
{
    /* Function to find the cross over point (the point before
       which elements are smaller than or equal to x and after
       which greater than x)*/
    int findCrossOver(int arr[], int low, int high, int x)
    {
        // Base cases
        if (arr[high] <= x) // x is greater than all
            return high;
        if (arr[low] > x)  // x is smaller than all
            return low;
 
        // Find the middle point
        int mid = (low + high)/2/* low + (high - low)/2 */
 
        /* If x is same as middle element, then return mid */
        if (arr[mid] <= x && arr[mid+1] > x)
            return mid;
 
        /* If x is greater than arr[mid], then either arr[mid + 1]
          is ceiling of x or ceiling lies in arr[mid+1...high] */
        if(arr[mid] < x)
            return findCrossOver(arr, mid+1, high, x);
 
        return findCrossOver(arr, low, mid - 1, x);
    }
 
    // This function prints k closest elements to x in arr[].
    // n is the number of elements in arr[]
    void printKclosest(int arr[], int x, int k, int n)
    {
        // Find the crossover point
        int l = findCrossOver(arr, 0, n-1, x);
        int r = l+1;   // Right index to search
        int count = 0; // To keep track of count of elements
                       // already printed
 
        // If x is present in arr[], then reduce left index
        // Assumption: all elements in arr[] are distinct
        if (arr[l] == x) l--;
 
        // Compare elements on left and right of crossover
        // point to find the k closest elements
        while (l >= 0 && r < n && count < k)
        {
            if (x - arr[l] < arr[r] - x)
                System.out.print(arr[l--]+" ");
            else
                System.out.print(arr[r++]+" ");
            count++;
        }
 
        // If there are no more elements on right side, then
        // print left elements
        while (count < k && l >= 0)
        {
            System.out.print(arr[l--]+" ");
            count++;
        }
 
 
        // If there are no more elements on left side, then
        // print right elements
        while (count < k && r < n)
        {
            System.out.print(arr[r++]+" ");
            count++;
        }
    }
 
    /* Driver program to check above functions */
    public static void main(String args[])
    {
        KClosest ob = new KClosest();
        int arr[] = {12, 16, 22, 30, 35, 39, 42,
                     45, 48, 50, 53, 55, 56
                    };
        int n = arr.length;
        int x = 35, k = 4;
        ob.printKclosest(arr, x, 4, n);
    }
}
/* This code is contributed by Rajat Mishra */

                    

Python3

# Function to find the cross over point
# (the point before which elements are
# smaller than or equal to x and after
# which greater than x)
def findCrossOver(arr, low, high, x) :
 
    # Base cases
    if (arr[high] <= x) : # x is greater than all
        return high
         
    if (arr[low] > x) : # x is smaller than all
        return low
     
    # Find the middle point
    mid = (low + high) // 2 # low + (high - low)// 2
     
    # If x is same as middle element,
    # then return mid
    if (arr[mid] <= x and arr[mid + 1] > x) :
        return mid
     
    # If x is greater than arr[mid], then
    # either arr[mid + 1] is ceiling of x
    # or ceiling lies in arr[mid+1...high]
    if(arr[mid] < x) :
        return findCrossOver(arr, mid + 1, high, x)
     
    return findCrossOver(arr, low, mid - 1, x)
 
# This function prints k closest elements to x
# in arr[]. n is the number of elements in arr[]
def printKclosest(arr, x, k, n) :
     
    # Find the crossover point
    l = findCrossOver(arr, 0, n - 1, x)
    r = l + 1 # Right index to search
    count = 0 # To keep track of count of
              # elements already printed
 
    # If x is present in arr[], then reduce
    # left index. Assumption: all elements
    # in arr[] are distinct
    if (arr[l] == x) :
        l -= 1
 
    # Compare elements on left and right of crossover
    # point to find the k closest elements
    while (l >= 0 and r < n and count < k) :
         
        if (x - arr[l] < arr[r] - x) :
            print(arr[l], end = " ")
            l -= 1
        else :
            print(arr[r], end = " ")
            r += 1
        count += 1
 
    # If there are no more elements on right
    # side, then print left elements
    while (count < k and l >= 0) :
        print(arr[l], end = " ")
        l -= 1
        count += 1
 
    # If there are no more elements on left
    # side, then print right elements
    while (count < k and r < n) :
        print(arr[r], end = " ")
        r += 1
        count += 1
 
# Driver Code
if __name__ == "__main__" :
 
    arr =[12, 16, 22, 30, 35, 39, 42,
              45, 48, 50, 53, 55, 56]
                 
    n = len(arr)
    x = 35
    k = 4
     
    printKclosest(arr, x, 4, n)
     
# This code is contributed by Ryuga

                    

C#

// C# program to find k closest elements to
// a given value
using System;
 
class GFG {
     
    /* Function to find the cross over point
    (the point before which elements are
    smaller than or equal to x and after which
    greater than x)*/
    static int findCrossOver(int []arr, int low,
                                int high, int x)
    {
         
        // Base cases
        // x is greater than all
        if (arr[high] <= x)
            return high;
             
        // x is smaller than all
        if (arr[low] > x)
            return low;
 
        // Find the middle point
        /* low + (high - low)/2 */
        int mid = (low + high)/2;
 
        /* If x is same as middle element, then
        return mid */
        if (arr[mid] <= x && arr[mid+1] > x)
            return mid;
 
        /* If x is greater than arr[mid], then
        either arr[mid + 1] is ceiling of x or
        ceiling lies in arr[mid+1...high] */
        if(arr[mid] < x)
            return findCrossOver(arr, mid+1,
                                      high, x);
 
        return findCrossOver(arr, low, mid - 1, x);
    }
 
    // This function prints k closest elements
    // to x in arr[]. n is the number of
    // elements in arr[]
    static void printKclosest(int []arr, int x,
                                  int k, int n)
    {
         
        // Find the crossover point
        int l = findCrossOver(arr, 0, n-1, x);
         
        // Right index to search
        int r = l + 1;
         
        // To keep track of count of elements
        int count = 0;
 
        // If x is present in arr[], then reduce
        // left index Assumption: all elements in
        // arr[] are distinct
        if (arr[l] == x) l--;
 
        // Compare elements on left and right of
        // crossover point to find the k closest
        // elements
        while (l >= 0 && r < n && count < k)
        {
            if (x - arr[l] < arr[r] - x)
                Console.Write(arr[l--]+" ");
            else
                Console.Write(arr[r++]+" ");
            count++;
        }
 
        // If there are no more elements on right
        // side, then print left elements
        while (count < k && l >= 0)
        {
            Console.Write(arr[l--]+" ");
            count++;
        }
 
        // If there are no more elements on left
        // side, then print right elements
        while (count < k && r < n)
        {
            Console.Write(arr[r++] + " ");
            count++;
        }
    }
 
    /* Driver program to check above functions */
    public static void Main()
    {
        int []arr = {12, 16, 22, 30, 35, 39, 42,
                         45, 48, 50, 53, 55, 56};
        int n = arr.Length;
        int x = 35;
        printKclosest(arr, x, 4, n);
    }
}
 
// This code is contributed by nitin mittal.

                    

Javascript

<script>
 
// JavaScript program to find k
// closest elements to a given value
 
// Function to find the cross over point
// (the point before which elements are
// smaller than or equal to x and after
// which greater than x)
function findCrossOver(arr, low, high, x)
{
     
    // Base cases
    if (arr[high] <= x)  // x is greater than all
        return high
         
    if (arr[low] > x)  // x is smaller than all
        return low
     
    // Find the middle point
    var mid = (low + high) // 2 // low + (high - low)// 2
     
    // If x is same as middle element,
    // then return mid
    if (arr[mid] <= x && arr[mid + 1] > x)
        return mid
     
    // If x is greater than arr[mid], then
    // either arr[mid + 1] is ceiling of x
    // or ceiling lies in arr[mid+1...high]
    if (arr[mid] < x)
        return findCrossOver(arr, mid + 1, high, x)
     
    return findCrossOver(arr, low, mid - 1, x)
     
}
 
// This function prints k closest elements to x
// in arr[]. n is the number of elements in arr[]
function printKclosest(arr, x, k, n)
{
     
    // Find the crossover point
    var l = findCrossOver(arr, 0, n - 1, x)
    var r = l + 1 // Right index to search
    var count = 0 // To keep track of count of
                  // elements already printed
     
    // If x is present in arr[], then reduce
    // left index. Assumption: all elements
    // in arr[] are distinct
    if (arr[l] == x)
        l -= 1
         
    // Compare elements on left and right of crossover
    // point to find the k closest elements
    while (l >= 0 && r < n && count < k)
    {
         
        if (x - arr[l] < arr[r] - x)
        {
            document.write(arr[l] + " ")
            l -= 1
        }
        else
        {
            document.write(arr[r] + " ")
            r += 1
        }
        count += 1
    }
        
    // If there are no more elements on right
    // side, then print left elements
    while (count < k && l >= 0)
    {
        print(arr[l])
        l -= 1
        count += 1
    }
     
    // If there are no more elements on left
    // side, then print right elements
    while (count < k && r < n)
    {
        print(arr[r])
        r += 1
        count += 1
    }
}
 
// Driver Code
var arr = [ 12, 16, 22, 30, 35, 39, 42,
            45, 48, 50, 53, 55, 56 ]
                 
var n = arr.length
var x = 35
var k = 4
     
printKclosest(arr, x, 4, n)
     
// This code is contributed by AnkThon
 
</script>

                    

PHP

<?php
// PHP Program to Find k closest
// elements to a given value
 
/* Function to find the cross
   over point (the point before
   which elements are smaller
   than or equal to x and after
   which greater than x) */
function findCrossOver($arr, $low,
                       $high, $x)
{
     
    // Base cases
     
    // x is greater than all
    if ($arr[$high] <= $x)
        return $high;
         
    // x is smaller than all
    if ($arr[$low] > $x)
        return $low;
     
    // Find the middle point
    /* low + (high - low)/2 */
    $mid = ($low + $high)/2;
     
    /* If x is same as middle
       element, then return mid */
    if ($arr[$mid] <= $x and
        $arr[$mid + 1] > $x)
        return $mid;
     
    /* If x is greater than arr[mid],
       then either arr[mid + 1] is
       ceiling of x or ceiling lies
       in arr[mid+1...high] */
    if($arr[$mid] < $x)
        return findCrossOver($arr, $mid + 1,
                                 $high, $x);
     
    return findCrossOver($arr, $low,
                      $mid - 1, $x);
}
 
// This function prints k
// closest elements to x in arr[].
// n is the number of elements
// in arr[]
function printKclosest($arr, $x, $k, $n)
{
     
    // Find the crossover point
    $l = findCrossOver($arr, 0, $n - 1, $x);
     
    // Right index to search
    $r = $l + 1;
     
    // To keep track of count of
    // elements already printed
    $count = 0;
 
    // If x is present in arr[],
    // then reduce left index
    // Assumption: all elements
    // in arr[] are distinct
    if ($arr[$l] == $x) $l--;
 
    // Compare elements on left
    // and right of crossover
    // point to find the k
    // closest elements
    while ($l >= 0 and $r < $n
              and $count < $k)
    {
        if ($x - $arr[$l] < $arr[$r] - $x)
            echo $arr[$l--]," ";
        else
            echo $arr[$r++]," ";
        $count++;
    }
 
    // If there are no more
    // elements on right side,
    // then print left elements
    while ($count < $k and $l >= 0)
        echo $arr[$l--]," "; $count++;
 
    // If there are no more
    // elements on left side,
    // then print right elements
    while ($count < $k and $r < $n)
        echo $arr[$r++]; $count++;
}
 
// Driver Code
$arr =array(12, 16, 22, 30, 35, 39, 42,
                45, 48, 50, 53, 55, 56);
$n = count($arr);
$x = 35; $k = 4;
 
printKclosest($arr, $x, 4, $n);
 
// This code is contributed by anuj_67.
?>

                    

Output
39 30 42 45 

Time complexity: O(Logn + k).
Auxiliary Space: O(1), since no extra space has been used.

Approach 2: Using Priority Queue

This approach uses a priority queue (max heap) to maintain the k closest numbers to x. It iterates over the elements in the array and calculates their absolute differences from x. The pairs of absolute differences and negative values are pushed into the max heap. If the size of the max heap exceeds k, the element with the maximum absolute difference is removed. Finally, the top k elements from the max heap are extracted and stored in a result vector. The vector is then reversed to obtain the closest numbers in ascending order before being returned as the result.

Below is the implementation:

C++

#include <bits/stdc++.h>
using namespace std;
 
vector<int> findClosestElements(vector<int>& arr, int k,
                                int x)
{
    // Create a max heap to store the pairs of absolute
    // differences and negative values
    priority_queue<pair<int, int> > maxH;
 
    int n = arr.size();
 
    for (int i = 0; i < n; i++) {
        // Skip if the element is equal to x
        if (arr[i] == x)
            continue;
 
        // Calculate the absolute difference and add the
        // pair to the max heap
        maxH.push({ abs(arr[i] - x), -arr[i] });
 
        // If the size of the max heap exceeds k, remove the
        // element with the maximum absolute difference
        if (maxH.size() > k)
            maxH.pop();
    }
 
    // Store the result in a vector
    vector<int> result;
 
    // Retrieve the top k elements from the max heap
    while (!maxH.empty()) {
        // Get the top element from the max heap
        auto p = maxH.top();
        maxH.pop();
 
        // Add the negative value to the result vector
        result.push_back(-p.second);
    }
 
    // Reverse the result vector to get the closest numbers
    // in ascending order
    reverse(result.begin(), result.end());
 
    return result;
}
 
int main()
{
    vector<int> arr = { 12, 16, 22, 30, 35, 39, 42,
                        45, 48, 50, 53, 55, 56 };
    int k = 4, x = 35;
    vector<int> res = findClosestElements(arr, k, x);
    for (int i = 0; i < res.size(); i++) {
        cout << res[i] << " ";
    }
    cout << endl;
    return 0;
}

                    

Java

/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.*;
class GFG {
    // Create pair class which implements Comparable
    // interface
    static class Pair implements Comparable<Pair> {
        int absDiff;
        int ind;
        Pair(int f, int s)
        {
            absDiff = f;
            ind = s;
        }
        public int compareTo(GFG.Pair o)
        {
            // If there are two elements with the same
            // difference with X, the greater element is
            // given priority.
            if (absDiff == o.absDiff)
                return ind - o.ind;
            else
                return o.absDiff - absDiff;
        }
    }
    static int[] printKClosest(int[] nums, int n, int k,
                               int x)
    {
        PriorityQueue<Pair> maxHeap = new PriorityQueue<>();
        for (int i = 0; i < nums.length; i++) {
            int diff = Math.abs(nums[i] - x);
          //if nums[i] == x then no need to consider that element
            if (diff != 0)
                maxHeap.add(new Pair(diff, i));
          //if maxheap size exceeds k then remove the element with maximum absolute difference
            if (maxHeap.size() > k)
                maxHeap.poll();
        }
        int ans[] = new int[k];
        int j = 0;
        while (!maxHeap.isEmpty()) {
          //Add the remaining elements to the answer
            ans[j] = nums[maxHeap.poll().ind];
            j++;
        }
      // reverse the array to get elements closest elements in ascending order
        for (int i = 0; i < k / 2; i++) {
            int t = ans[i];
            ans[i] = ans[k - i - 1];
            ans[k - i - 1] = t;
        }
        return ans;
    }
    public static void main(String[] args)
    {
        int arr[] = { 12, 16, 22, 30, 35, 39, 42,
                      45, 48, 50, 53, 55, 56 };
        int k = 4, x = 35;
        int ans[] = printKClosest(arr, arr.length, k, x);
        System.out.println(Arrays.toString(ans));
    }
}

                    

Python3

# Python Code for the above approach
import heapq
 
 
def findClosestElements(arr, k, x):
    # Create a max heap to store the pairs of absolute differences and negative values
    max_heap = []
 
    for num in arr:
        # Skip if the element is equal to x
        if num == x:
            continue
 
        # Calculate the absolute difference and add the pair to the max heap
        diff = abs(num - x)
        heapq.heappush(max_heap, (-diff, num))
 
        # If the size of the max heap exceeds k, remove the element with the maximum absolute difference
        if len(max_heap) > k:
            heapq.heappop(max_heap)
 
    # Store the result in an array
    result = []
 
    # Retrieve the top k elements from the max heap
    while max_heap:
        # Get the top element from the max heap
        diff, num = heapq.heappop(max_heap)
 
        # Add the value to the result array
        result.append(num)
 
    # Return the closest numbers in ascending order
    return sorted(result)
 
 
# Test case
arr = [12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56]
k = 4
x = 35
res = findClosestElements(arr, k, x)
print(res)
# THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL

                    

C#

//C# Code for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    // Function to find the k closest elements to x in the given array
    static List<int> FindClosestElements(List<int> arr, int k, int x)
    {
        // Sort the array by absolute difference from x and then by value
        arr.Sort((a, b) => Math.Abs(a - x).CompareTo(Math.Abs(b - x)) == 0 ? a.CompareTo(b) : Math.Abs(a - x).CompareTo(Math.Abs(b - x)));
 
        // Take the first k elements as they will be the closest
        var result = arr.GetRange(0, k);
 
        return result;
    }
 
    static void Main()
    {
        // Test case
        List<int> arr = new List<int> { 12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56 };
        int k = 4;
        int x = 35;
 
        // Remove the value x from the list before finding the closest elements
        arr.Remove(x);
 
        List<int> res = FindClosestElements(arr, k, x);
 
        // Print the result
        Console.WriteLine(string.Join(" ", res));
    }
}

                    

Javascript

function findClosestElements(arr, k, x) {
    // Create a max heap to store the pairs of absolute
    // differences and negative values
    const maxH = new MaxHeap();
 
    const n = arr.length;
 
    for (let i = 0; i < n; i++) {
        // Skip if the element is equal to x
        if (arr[i] === x)
            continue;
 
        // Calculate the absolute difference and add the
        // pair to the max heap
        const diff = Math.abs(arr[i] - x);
        maxH.insert({ diff: diff, value: -arr[i] });
 
        // If the size of the max heap exceeds k, remove the
        // element with the maximum absolute difference
        if (maxH.size() > k)
            maxH.extractMax();
    }
 
    // Store the result in an array
    const result = [];
 
    // Retrieve the top k elements from the max heap
    while (!maxH.isEmpty()) {
        // Get the top element from the max heap
        const p = maxH.extractMax();
 
        // Add the negative value to the result array
        result.push(-p.value);
    }
 
    // Reverse the result array to get the closest numbers
    // in ascending order
    result.reverse();
 
    return result;
}
 
// MaxHeap class implementation
class MaxHeap {
    constructor() {
        this.heap = [];
    }
 
    size() {
        return this.heap.length;
    }
 
    isEmpty() {
        return this.heap.length === 0;
    }
 
    insert(value) {
        this.heap.push(value);
        this.heapifyUp(this.heap.length - 1);
    }
 
    extractMax() {
        if (this.isEmpty())
            return null;
 
        const max = this.heap[0];
        const lastElement = this.heap.pop();
 
        if (!this.isEmpty()) {
            this.heap[0] = lastElement;
            this.heapifyDown(0);
        }
 
        return max;
    }
 
    heapifyUp(index) {
        const parentIndex = Math.floor((index - 1) / 2);
 
        if (parentIndex >= 0 && this.heap[parentIndex].diff <
            this.heap[index].diff) {
            this.swap(parentIndex, index);
            this.heapifyUp(parentIndex);
        }
    }
 
    heapifyDown(index) {
        const leftChildIndex = 2 * index + 1;
        const rightChildIndex = 2 * index + 2;
        let largestIndex = index;
 
        if (leftChildIndex < this.heap.length &&
        this.heap[leftChildIndex].diff >
        this.heap[largestIndex].diff) {
            largestIndex = leftChildIndex;
        }
 
        if (rightChildIndex < this.heap.length &&
        this.heap[rightChildIndex].diff >
        this.heap[largestIndex].diff) {
            largestIndex = rightChildIndex;
        }
 
        if (largestIndex !== index) {
            this.swap(largestIndex, index);
            this.heapifyDown(largestIndex);
        }
    }
 
    swap(index1, index2) {
        [this.heap[index1], this.heap[index2]] =
        [this.heap[index2], this.heap[index1]];
    }
}
 
// Test case
const arr = [12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56];
const k = 4;
const x = 35;
const res = findClosestElements(arr, k, x);
console.log(res);

                    

Output
39 30 42 45 


Time Complexity: O(n log k), where n is the size of the array and k is the number of elements to be returned. The priority queue takes O(log k) time to insert an element and O(log k) time to remove the top element. Therefore, traversing through the array and inserting elements into the priority queue takes O(n log k) time. Popping elements from the priority queue and pushing them into the result vector takes O(k log k) time. Therefore, the total time complexity is O(n log k + k log k) which is equivalent to O(n log k).
Auxiliary Space: O(k), as we are using a priority queue of size k+1 and a vector of size k to store the result.

Exercise: Extend the optimized solution to work for duplicates also, i.e., to work for arrays where elements don’t have to be distinct.

Approach 3: Two Pointer Approach

Initialization:

  • Initialize two pointers, left and right, pointing to the start and end of the array, respectively.

Binary Search:

  • Use a binary search-like approach to narrow down the range until right – left >= k.
  • Compare the absolute differences of the elements at left and right with the target.
  • Move the pointers accordingly to minimize the absolute difference.

Print Result:

  • Print the k closest elements within the narrowed down range.

C++

#include <iostream>
using namespace std;
 
void findKClosestElements(int nums[], int target, int k, int n)
{
    int left = 0;
    int right = n;
  
    while (right - left >= k)
    {
        if (abs(nums[left] - target) > abs(nums[right] - target)) {
            left++;
        }
        else {
            right--;
        }
    }
  
    // print the `k` closest elements
    while (left <= right)
    {
           cout<<nums[left]<< " ";;
        left++;
    }
}
  
int main(void)
{
    int nums[] = { 12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56  };
    int n = sizeof(nums) / sizeof(nums[0]);
  
    int target = 35, k = 4;
  
    findKClosestElements(nums, target, k, n);
  
    return 0;
}

                    

Java

import java.util.Arrays;
 
public class KClosestElements {
     
    // Function to find k closest elements to the target in the array
    static void findKClosestElements(int[] nums, int target, int k, int n) {
        int left = 0;
        int right = n - 1;
 
        // Iterate until the difference between right and left pointers is >= k
        while (right - left >= k) {
            // Compare absolute differences between target and elements
            // at left and right pointers
            // Move the pointers closer to the target by updating left/
            // right based on the closest element
            if (Math.abs(nums[left] - target) > Math.abs(nums[right] - target)) {
                left++;
            } else {
                right--;
            }
        }
 
        // Print the k closest elements
        while (left <= right) {
            System.out.print(nums[left] + " ");
            left++;
        }
    }
 
    public static void main(String[] args) {
        int[] nums = { 12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56 };
        int n = nums.length;
 
        int target = 35, k = 4;
 
        // Call the function to find and print k closest elements to the target
        findKClosestElements(nums, target, k, n);
    }
}

                    

Python3

def find_k_closest_elements(nums, target, k, n):
    left = 0
    right = n - 1
 
    # Use binary search to find the closest elements
    while right - left >= k:
        # Compare the absolute differences between the target and elements at left and right pointers
        if abs(nums[left] - target) > abs(nums[right] - target):
            left += 1
        else:
            right -= 1
 
    # Print the `k` closest elements
    while left <= right:
        print(nums[left], end=" ")
        left += 1
 
if __name__ == "__main__":
    nums = [12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56]
    n = len(nums)
 
    target = 35
    k = 4
 
    # Find and print the k closest elements to the target
    find_k_closest_elements(nums, target, k, n)

                    

C#

using System;
 
class Program
{
    // Function to find and print the K closest elements to the target in the given array
    static void FindKClosestElements(int[] nums, int target, int k, int n)
    {
        // Initialize two pointers, 'left' and 'right'
        int left = 0;
        int right = n;
 
        // Continue the loop until the difference between 'right' and 'left' is greater than 'k'
        while (right - left > k)
        {
            // Compare the absolute differences of elements at 'left' and 'right - 1' with the target
            if (Math.Abs(nums[left] - target) > Math.Abs(nums[right - 1] - target))
            {
                // If the left element is farther from the target, move 'left' pointer to the right
                left++;
            }
            else
            {
                // If the right element is farther from the target, move 'right' pointer to the left
                right--;
            }
        }
 
        // Print the `k` closest elements between the 'left' and 'right' pointers
        for (int i = left; i < right; i++)
        {
            Console.Write(nums[i] + " ");
        }
    }
 
    // Main method, entry point of the program
    static void Main()
    {
        // Given sorted array
        int[] nums = { 12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56 };
        int n = nums.Length; // Length of the array
 
        int target = 35, k = 4; // Target value and the number of closest elements to find
 
        // Call the function to find and print the K closest elements
        FindKClosestElements(nums, target, k, n);
 
        // ReadLine to keep the console window open until user presses Enter
        Console.ReadLine();
    }
}
 
 
// This code is contributed by shivamgupta310570

                    

Javascript

function find_k_closest_elements(nums, target, k, n) {
    let left = 0;
    let right = n - 1;
 
    // Use binary search to find the closest elements
    while (right - left >= k) {
        // Compare the absolute differences between the target and elements at left and right pointers
        if (Math.abs(nums[left] - target) > Math.abs(nums[right] - target)) {
            left++;
        } else {
            right--;
        }
    }
 
    // Print the `k` closest elements
    while (left <= right) {
        console.log(nums[left], end=" ");
        left++;
    }
}
 
// Driver Code
if (true) {
    const nums = [12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56];
    const n = nums.length;
 
    const target = 35;
    const k = 4;
 
    // Find and print the k closest elements to the target
    find_k_closest_elements(nums, target, k, n);
}

                    

Output
30 35 39 42 

The time complexity of the above solution is O(n) and doesn’t require any extra space.




Last Updated : 02 Feb, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads