首页 > 代码库 > Coursera Algorithms week1 Interview Questions: Search in a bitonic array

Coursera Algorithms week1 Interview Questions: Search in a bitonic array

题目要求:

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方法。

 1 public class SearchBitonicArray {
 2     private static int seachLeft(int key,int[] a, int lo, int hi){
 3         int mid = 0;
 4         while(lo <= hi){//遍历左侧增长序列
 5             mid = lo + (hi-lo)/2;
 6             if(key > a[mid]) lo = mid +1;
 7             else if(key < a[mid]) hi = mid -1;
 8             else return mid;
 9         }
10         return -1;
11     }
12     private static int searchRight(int key, int[] a, int lo, int hi){
13         int mid = 0;
14         while(lo <= hi){
15             mid = lo + (hi-lo)/2;
16             if(key > a[mid]) hi = mid -1;
17             else if(key < a[mid]) lo = mid +1;
18             else return mid;
19         }
20         return -1;
21     }
22     
23     //worst case use 3lgn
24     public static int findNormal(int key, int[] a){
25         int lo = 0;
26         int hi = a.length -1;
27         int mid = 0;
28         while(lo<=hi){
29             mid = lo + (hi-lo)/2;
30             if(a[mid]==key) return mid;
31             else{
32                 if(mid==0 || mid==a.length-1) return -1;
33                 if(a[mid]>a[mid-1] && a[mid]>a[mid+1]){//mid刚好取到最大数
34                     break;
35                 }else if(a[mid]>a[mid-1] && a[mid]<a[mid+1]){//mid取在增长序列
36                     lo = mid +1;
37                 }else{//mid取在衰减序列
38                     hi = mid -1;
39                 }
40             }
41         }
42         //循环结束,但没有return,说明key未找到,并且mid此时已经是取到最大数
43         int maxValIndex = mid;
44         if(key > a[maxValIndex]) return -1;//key大于a[i]中最大值,key肯定不在数组中
45         if(key < a[0] && key < a[a.length -1]) return -1;
46         int findValue = http://www.mamicode.com/seachLeft(key,a,0,maxValIndex-1);
47         if(findValue =http://www.mamicode.com/= -1)
48             findValue = http://www.mamicode.com/searchRight(key,a,maxValIndex+1,a.length-1);
49         
50         return findValue;
51     }
52     
53     public static int findFast(int key, int[] a){
54         int lo = 0;
55         int hi = a.length -1;
56         int mid = 0;
57         int findValue = http://www.mamicode.com/-1;
58         while(lo<=hi){
59             mid = lo + (hi-lo)/2;
60             if(a[mid]==key) return mid;
61             else if(a[mid] > key){
62                 if(a[mid]>a[mid+1] && a[mid]>a[mid-1]){
63                     findValue = http://www.mamicode.com/seachLeft(key,a,0,mid-1);
64                     if(findValue != -1) return findValue;
65                     else return searchRight(key,a,mid+1,a.length-1);
66                 }else if(a[mid]>a[mid+1] && a[mid]<a[mid-1]){
67                     hi = mid-1;
68                 }else{
69                     lo = mid +1;
70                 }
71             }else{//说明key值可能在a[mid]的两边
72                 findValue = http://www.mamicode.com/seachLeft(key,a,0,mid-1);
73                 if(findValue != -1) return findValue;
74                 else return searchRight(key,a,mid+1,a.length-1);
75             }
76         }
77         return -1;
78     }
79 
80     public static void main(String[] args){
81         int[] a = {5,6,7,8,9,3,2,1,0};
82         System.out.println(SearchBitonicArray.findNormal(4, a));
83         System.out.println(SearchBitonicArray.findFast(4, a));
84     }
85 }

 

Coursera Algorithms week1 Interview Questions: Search in a bitonic array