旋转数组的二分查找

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;
	}

3、旋转数组的二分查找之找出最小值

找出旋转数组中最小值。算法大概思路:首先利用两个索引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;
}

后记:

积跬步,致千里

点赞