题目重述:
- 3lgn可能的解法:
思路:
step -1 :获得array的最大、最小值。复杂度logn;
step-2 :最大值左侧、右侧依次进行二分查找。复杂度2logn.
public class SearchBitonicArray {
private static int seachLeft(int *array, int left, int right, int key){
int mid = 0;
while(left <= right){//遍历左侧增长序列
mid = (left + right)/2;
if(key > array[mid]) left = mid +1;
else if(key < array[mid]) right = mid -1;
else return mid;
}
return -1;
}
private static int searchRight(int *array, int left, int right, int key){
int mid = 0;
while(left <= right){
mid = (left+right)/2;
if(key > array[mid]) right = mid -1;
else if(key < array[mid]) left = mid +1;
else return mid;
}
return -1;
}
//worst case use 3lgn
public static bool findNormal(int *array, int key){
int left = 0, right = a.length -1, mid = 0;
while(left <= right){ // 数组的获取最大值,O(logn)
mid = (left + right)/2;
if( array[mid] == key) return true;
else{
if(mid==0 || mid == array.length-1) return -1;
if(array[mid]>array[mid-1] && array[mid]>array[mid+1]) break;
else if(array[mid]>array[mid-1] && array[mid]<array[mid+1]) left = mid +1;
else right = mid -1;
}
}
int maxValIndex = mid;
if(key > array[maxValIndex] || (key < array[0] && key < array[array.length -1])) return false;
int ans_left = seachLeft(array, 0, maxValIndex-1, key);
int ans_right = seachRight(array, maxValIndex, array.length -1, key);
if(ans_left + ans_right != -2) return true;
else return false;
}
public static int findFast(int key, int[] a){
int lo = 0;
int hi = a.length -1;
int mid = 0;
int findValue = -1;
while(lo<=hi){
mid = lo + (hi-lo)/2;
if(a[mid]==key) return mid;
else if(a[mid] > key){
if(a[mid]>a[mid+1] && a[mid]>a[mid-1]){
findValue = seachLeft(key,a,0,mid-1);
if(findValue != -1) return findValue;
else return searchRight(key,a,mid+1,a.length-1);
}else if(a[mid]>a[mid+1] && a[mid]<a[mid-1]){
hi = mid-1;
}else{
lo = mid +1;
}
}else{//说明key值可能在a[mid]的两边
findValue = seachLeft(key,a,0,mid-1);
if(findValue != -1) return findValue;
else return searchRight(key,a,mid+1,a.length-1);
}
}
return -1;
}
}