I was making an algorithm for a task I found in a book. It says that there is sorted array, that was swapped so it looks like "4567123", and was proposed to use binary search modification.
Below is my solution in java.
The thing is, I'm a bit cringed that I can't process cases for array size of 2, 3 generically (for case of size 1 it's obvious that it'll require a specific case). Not that I need a solution that'll do that generically for 2, 3 array size cases. But I more like to know, is it a problem. Also I addressed a problem when array wasn't swaped at all. And I'm not sure that I should've done this, if preconditions are clearly specified. Btw binary search doesn't check that it's input is sorted.
So, more what I need is not code review itself, but more of advise, is my hardcoded cases and support for nonswaped array is good or bad. I myself believe that cases are fine, as algorithm compares 2 values, and thus requires at least 2 values to be compared, also it searches for the "peak and drop". But I'll probably try to modify it so it won't cover non-swaped array case and generically work for 2, 3 size array.
//file SwapedArraySearch.java\
public class SwapedArraySearch {
public static int search(int[] arr) {
switch (arr.length){
case 1:
return arr[0];
case 2:
return arr[0] > arr[1]?arr[1]:arr[0];
case 3:
return arr[0] > arr [1] ? (arr[1] > arr[2]?arr[2]: arr[1]):
(arr[0] > arr[2]?arr[2]: arr[0]);
}
int x = arr[0];
int n = arr.length/2;
int prevn = arr[n] > x ? arr.length -1 : 1;
int t;
while(prevn != n) {
if (x < arr[n]) {
if (arr[n] > arr [n + 1] )
return arr[n+1];
t = n;
n = n + (prevn - n)/2;
prevn = t;
} else {
if (arr[n - 1] > arr[n])
return arr[n];
t = n;
n = prevn + (n - prevn)/2;
prevn = t;
}
}
return arr[0] > arr[1] ? arr[arr.length - 1] : arr[0];
}
public static void main(String... args) {
int[] arr = new int[args.length];
for (int i = 0; i < args.length; i++)
arr[i] = Integer.valueOf(args[i]);
System.out.println(search(arr));
}
}
EDIT: the task is to find the lowest element
EDIT2: after much more thinking I boiled down my search function to this:
x = arr[arr.length - 1]
a = 0
b = arr.length
while b - a > 2
if x > arr[(a+b)/2]
b = (a+b)/2
else
a = (a+b)/2
return arr[(a+b)/2]
the key point to simplification was to understand that middle element can always be calculated as (a+b)/2
.
mid = (a+b)/2
risks integer overflow for large arrays. \$\endgroup\$