题目要求:
An array is bitonic if it is comprised of an increasing sequence of integers followed immediately by a decreasing sequence of integers. Write a program that, given a bitonic array of n distinct integer values, determines whether a given integer is in the array.
- Standard version: Use ∼3lgn compares in the worst case.
- Signing bonus: Use ∼2lgn compares in the worst case (and prove that no algorithm can guarantee to perform fewer than ∼2lgn compares in the worst case).
分析
bitonic array是一个内部先递增再递减的队列,实现3lgn很简单,先找出最大值用掉lgn,再从左侧有序数组中查找用掉lgn,未找到则再从右侧有序数组中查找用掉lgn,最坏情况下复杂度就是3lgn。详见代码中findNormal方法。
但是2lgn的做法我一直没想出来合适的,作业的hint提示“Signing bonus. Do it without finding the maximum integer.”意味着去掉查找最大值可以减少复杂度。我一时也没想到好的实现方法,在网上看到一篇别人转载的文章后恍然大悟(http://blog.csdn.net/fiveyears/article/details/11263381)。参照其思路,自己实现findFast方法。
public class SearchBitonicArray {
private static int seachLeft(int key,int[] a, int lo, int hi){
int mid = 0;
while(lo <= hi){//遍历左侧增长序列
mid = lo + (hi-lo)/2;
if(key > a[mid]) lo = mid +1;
else if(key < a[mid]) hi = mid -1;
else return mid;
}
return -1;
}
private static int searchRight(int key, int[] a, int lo, int hi){
int mid = 0;
while(lo <= hi){
mid = lo + (hi-lo)/2;
if(key > a[mid]) hi = mid -1;
else if(key < a[mid]) lo = mid +1;
else return mid;
}
return -1;
}
//worst case use 3lgn
public static int findNormal(int key, int[] a){
int lo = 0;
int hi = a.length -1;
int mid = 0;
while(lo<=hi){
mid = lo + (hi-lo)/2;
if(a[mid]==key) return mid;
else{
if(mid==0 || mid==a.length-1) return -1;
if(a[mid]>a[mid-1] && a[mid]>a[mid+1]){//mid刚好取到最大数
break;
}else if(a[mid]>a[mid-1] && a[mid]
a[maxValIndex]) return -1;//key大于a[i]中最大值,key肯定不在数组中
if(key < a[0] && key < a[a.length -1]) return -1;
int findValue = seachLeft(key,a,0,maxValIndex-1);
if(findValue == -1)
findValue = searchRight(key,a,maxValIndex+1,a.length-1);
return findValue;
}
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]
本文探讨如何在位序数组(先递增后递减的整数数组)中寻找特定元素。标准方法使用约3lgN次比较,而挑战在于设计一种使用约2lgN次比较的算法。文章通过分析和代码实现,解释了两种方法的原理,特别是如何在不寻找最大值的情况下优化到2lgN的时间复杂度。

759

被折叠的 条评论
为什么被折叠?



