Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the nearest/closest value in a sorted List [duplicate]

I was wondering if it is possible to find the closest element in a sorted List for a element that is not in the list.

For example if we had the values [1,3,6,7] and we are looking for the element closest to 4, it should return 3, because 3 is the biggest number in the array, that is smaller than 4.

I hope it makes sense, because English is not my native language.

like image 555
drBet Avatar asked May 14 '15 18:05

drBet


People also ask

How do you find the closest value in a list?

We can find the nearest value in the list by using the min() function. Define a function that calculates the difference between a value in the list and the given value and returns the absolute value of the result. Then call the min() function which returns the closest value to the given value.

How do you find the closest value to a number in an array?

Therefore, to find out the closest number we just return the index of the found minimum in the given array indexArr. indexOf(min) .

How do you find the closest number in an array in binary search?

A simple solution is to traverse through the given array and keep track of absolute difference of current element with every element. Finally return the element that has minimum absolution difference. An efficient solution is to use Binary Search.


2 Answers

Because the collection is sorted, you can do a modified binary search in O( log n ) :

    public static int search(int value, int[] a) {          if(value < a[0]) {             return a[0];         }         if(value > a[a.length-1]) {             return a[a.length-1];         }          int lo = 0;         int hi = a.length - 1;          while (lo <= hi) {             int mid = (hi + lo) / 2;              if (value < a[mid]) {                 hi = mid - 1;             } else if (value > a[mid]) {                 lo = mid + 1;             } else {                 return a[mid];             }         }         // lo == hi + 1         return (a[lo] - value) < (value - a[hi]) ? a[lo] : a[hi];     } 

Since most of the code above is binary search, you can leverage the binarySearch(...) provided in the std library and examine the value of the insertion point:

    public static int usingBinarySearch(int value, int[] a) {         if (value <= a[0]) { return a[0]; }         if (value >= a[a.length - 1]) { return a[a.length - 1]; }          int result = Arrays.binarySearch(a, value);         if (result >= 0) { return a[result]; }          int insertionPoint = -result - 1;         return (a[insertionPoint] - value) < (value - a[insertionPoint - 1]) ?                 a[insertionPoint] : a[insertionPoint - 1];     }  
like image 176
David Soroko Avatar answered Sep 20 '22 14:09

David Soroko


You need Array.binarySearch, docs.

Returns: index of the search key, if it is contained in the array; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the array: the index of the first element greater than the key, or a.length if all elements in the array are less than the specified key.

like image 35
Andrey Avatar answered Sep 18 '22 14:09

Andrey