I have a sorted list which is rotated and would like to do a binary search on that list to find the minimum element.
Lets suppose initial list is {1,2,3,4,5,6,7,8} rotated list can be like {5,6,7,8,1,2,3,4}
Normal binary search doesn't work in this case. Any idea how to do this.
-- Edit
I have one another condition. What if the list is not sorted??
Approach to Find the Point of RotationStart traversing the array from the beginning. There will be a index in the array where the value stored at the index will be smaller than the value at the previous index. Return the index.
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]):
A slight modification on the binary search algorithm is all you need; here's the solution in complete runnable Java (see Serg's answer for Delphi implementation, and tkr's answer for visual explanation of the algorithm).
import java.util.*;
public class BinarySearch {
static int findMinimum(Integer[] arr) {
int low = 0;
int high = arr.length - 1;
while (arr[low] > arr[high]) {
int mid = (low + high) >>> 1;
if (arr[mid] > arr[high]) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
public static void main(String[] args) {
Integer[] arr = { 1, 2, 3, 4, 5, 6, 7 };
// must be in sorted order, allowing rotation, and contain no duplicates
for (int i = 0; i < arr.length; i++) {
System.out.print(Arrays.toString(arr));
int minIndex = findMinimum(arr);
System.out.println(" Min is " + arr[minIndex] + " at " + minIndex);
Collections.rotate(Arrays.asList(arr), 1);
}
}
}
This prints:
[1, 2, 3, 4, 5, 6, 7] Min is 1 at 0
[7, 1, 2, 3, 4, 5, 6] Min is 1 at 1
[6, 7, 1, 2, 3, 4, 5] Min is 1 at 2
[5, 6, 7, 1, 2, 3, 4] Min is 1 at 3
[4, 5, 6, 7, 1, 2, 3] Min is 1 at 4
[3, 4, 5, 6, 7, 1, 2] Min is 1 at 5
[2, 3, 4, 5, 6, 7, 1] Min is 1 at 6
Integer[]
instead of int[]
>>> 1
instead of / 2
Note that duplicates makes it impossible to do this in O(log N)
. Consider the following bit array consisting of many 1
, and one 0
:
(sorted)
01111111111111111111111111111111111111111111111111111111111111111
^
(rotated)
11111111111111111111111111111111111111111111101111111111111111111
^
(rotated)
11111111111111101111111111111111111111111111111111111111111111111
^
This array can be rotated in N
ways, and locating the 0
in O(log N)
is impossible, since there's no way to tell if it's in the left or right side of the "middle".
I have one another condition. What if the list is not sorted??
Then, unless you want to sort it first and proceed from there, you'll have to do a linear search to find the minimum.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With