1.4.20双调查找。如果一个数组中的所有元素是先递增后递减的,则称这个数组为双调的。编写一个程序,给定一个含有N个不同int值的双调数组,判断它是否含有给定的整数。程序在最坏情况下所需的比较次数为~3lgN。
答:第一步找出数组中的最大值索引,然后将数组从最大值索引位置一分为二,将数组分为单调递增和单调递减的两个数组,再在这两个数组中使用二分查找。
public class E1d4d20
{
public static int rank(int[] a,int key)
{
int maxindex=maxIndex(a);
int upIndex=rankUp(a,0,maxindex,key);
StdOut.println("key="+key);
StdOut.println("maxIndex="+maxindex);
StdOut.println("upIndex="+upIndex);
if (upIndex>-1)
return upIndex;
else
return rankDown(a,maxindex+1,a.length-1,key);
}
private static int maxIndex(int[] a)
{
int lo=0;
int hi=a.length-1;
int mid;
while(lo<hi)
{
mid=(lo+hi)/2;
if (a[mid]<a[mid+1])
lo=mid+1;
else if(a[mid]>a[mid+1])
hi=mid;
}
return lo;
}
private static int rankUp(int[] a,int lo,int hi,int key)
{
int mid;
while(lo<=hi)
{
mid=(lo+hi)/2;
if(key<a[mid])
hi=mid-1;
else if(key>a[mid])
lo=mid+1;
else
return mid;
}
return -1;
}
private static int rankDown(int[] a,int lo,int hi,int key)
{
int mid;
while(lo<=hi)
{
mid=(lo+hi)/2;
if(key<a[mid])
lo=mid+1;
else if(key>a[mid])
hi=mid-1;
else
return mid;
}
return -1;
}
public static void main(String[] args)
{
int[] a=In.readInts(args[0]);
int key=Integer.parseInt(args[1]);
StdOut.println(rank(a,key));
}
}