Find k closest elements to a given value - GeeksforGeeks

13 Apr, 2021
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.
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++
Java
Python3
C#
PHP
Javascript
#include<stdio.h> /* Function to find the cross over point (the point beforewhich elements are smaller than or equal to x and afterwhich greater than x)*/int findCrossOver(int arr[], int low, int high, int x){// Base casesif (arr[high] <= x) // x is greater than all    return high;if (arr[low] > x) // x is smaller than all    return low; // Find the middle pointint 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 program to find k closest elements to a given valueclass 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 */
# 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 Codeif __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# program to find k closest elements to// a given valueusing 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.
<?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.?>
<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 Codevar arr = [ 12, 16, 22, 30, 35, 39, 42,            45, 48, 50, 53, 55, 56 ]                 var n = arr.lengthvar x = 35var k = 4     printKclosest(arr, x, 4, n)     // This code is contributed by AnkThon </script>
Output: 
39 30 42 45
The time complexity of this method is O(Logn + k).Exercise: Extend the optimized solution to work for duplicates also, i.e., to work for arrays where elements don’t have to be distinct.This article is contributed by Rahul Jain. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
nitin mittal
vt_m
ankthon
Amazon
Arrays
Searching
Amazon
Arrays
Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Introduction to Arrays
Binary Search
Maximum and minimum of an array using minimum number of comparisons
Linear Search
Find the Missing Number
Search an element in a sorted and rotated array