Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary search modification on unknown shift

Suppose I have a sorted array [1, 2, 3, 4, 5, 6]. I can apply binary search to find any number but what modification in my binary search logic I have to do If my sorted array shifted left by some unknown number. Like [4, 5, 6, 1, 2, 3].

like image 276
Sumeet Kumar Yadav Avatar asked Feb 11 '15 19:02

Sumeet Kumar Yadav


People also ask

Does binary search work on rotated array?

You can use binary search on the rotated array (with some modifications). Let N be the number you are searching for: Read the first number (arr[start]) and the number in the middle of the array (arr[end]):

What is modified binary search?

Modified binary search algorithm optimizes the worst case of the binary search algorithm by comparing the input element with the first & last element of the data set along with the middle element and also checks the input number belongs to the range of numbers present in the given data set at each iteration there by ...

Why binary search does not work on unsorted data?

So, the answer is NO, it is not possible to use or implement Binary Search on unsorted arrays or lists, because, the repeated targeting of the mid element of one half depends on the sorted order of data structure.

Do binary searches need to be sorted to work?

Binary search is faster than linear search except for small arrays. However, the array must be sorted first to be able to apply binary search.


3 Answers

  1. We can find the shift using binary search. We need to find the first number which is less than the first element of the given array. Something like this:

    def getShift():
        if a[n - 1] > a[0]:
             return 0 // there is no shift
        low = 0 // definitely not less than a[0]
        high = n - 1 // definitely less than a[0]
        while high - low > 1:
            mid = (low + high) / 2
            if a[mid] < a[0]:
                high = mid
            else
                low = mid
        return high
    
  2. Now know the shift so we can run standard binary search over two intervals: [0, shift) and [shift, n - 1].

The time complexity is O(log n)(because we run 3 binary searches).

like image 171
kraskevich Avatar answered Nov 13 '22 21:11

kraskevich


Just re-sort the array after the unknown shift. It will be computationally expensive, but it will be correct.

Additionally, you could also just do a linear sort at this point, since sorting and searching will take O(n*log(n)). Doing a linear search via brute force will only be O(n).

like image 22
Lawrence Aiello Avatar answered Nov 13 '22 22:11

Lawrence Aiello


You only need to run through the regular binary search algorithm once, with a modification on the logic as to when to select the upper or lower search window. The modification is based on additional comparisons with the first element in the shifted array so that you know which segment of the array you are in. You can do this without having to actually find the precise location of the split.

In ruby:

LIST = [6,7,8,9,10,1,2,3,4,5]

def binary_search(x)
  first = LIST[0]
  low = 0
  high = LIST.size-1
  while low <= high
    mid = low + (high-low)/2 # avoid overflow
    return mid if x == LIST[mid]
    if (LIST[mid] < first) != (x < first) || LIST[mid] < x
      low = mid + 1
    else
      high = mid - 1
    end
  end
  return -1 # not found
end

1.upto(10) do |x|
  puts "#{x} found at index #{binary_search(x)}"
end

Output:

1 found at index 5
2 found at index 6
3 found at index 7
4 found at index 8
5 found at index 9
6 found at index 0
7 found at index 1
8 found at index 2
9 found at index 3
10 found at index 4
like image 30
Matt Avatar answered Nov 13 '22 21:11

Matt