1、什么是旋转数组
旋转数组是将一个有序数组的前若干个数旋转到数组末尾,例如数组a[5]={2,3,4,5,8} 那么数组b[5]={4,5,8,2,3}为数组a的一个旋转数组
2、旋转数组的二分查找之找到给定key
对于给定一个数key,如何从旋转数组中找到key的位置呢?由于旋转数组部分有序,故可以利用二分查找思想来设计算法,从而达到logn的时间复杂度。
代码如下:
public int rotateArraySearch(int[] a, int key) {
if (a == null)
return -1;
int low = 0, high = a.length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (a[mid] == key)
return mid;
if (a[mid] > a[low]) { // 表示左边有序
if (key >= a[low] && key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
} else { // 表示右边有序
if (key >= a[mid] && key < a[high]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
}
return -1;
}
找出旋转数组中最小值。算法大概思路:首先利用两个索引low,high指向数组a[ ]首尾元素,然后二分求mid,判断a[mid],若a[mid]>=a[low],则说明最小元素在右侧,那么令low=min;若a[mid]<a[high],则说明最小元素在左侧,那么令high=mid;如此反复进行直到high-low==1时停止(因为最终一定会出现high-low==1的情况,而且此时high索引所在的元素即为最小元素)。
另外要考虑有一个特例,就是当a[low==a[high]&&a[low]==a[mid]时,在这种情况下就只能遍历数组找出元素。原因如下:
代码如下:
public int rotateArrayMin(int[] a){
if(a==null){
System.out.print("The array is null\n");
System.exit(0);
}
int low=0,high=a.length-1;
int mid=low;
while(a[low]>=a[high]){
if(high-low==1){
mid=high;
break;
}
mid=low+((high-low)>>1);
if(a[low]==a[high]&&a[low]==a[mid]){
int result=getMinByOrder(a);
return result;
}
if(a[mid]>=a[low]){
low=mid;
}else{
high=mid;
}
}
return a[mid];
}
private int getMinByOrder(int[] a) {
// TODO Auto-generated method stub
int min=a[0];
int len=a.length;
for(int i=1;i<len;i++){
if(a[i]<min){
min=a[i];
}
}
return min;
}
后记:
积跬步,致千里