在左移递减数组中查找其中的某一个数(微软面试题)

 1 /*
 2 题目描述:一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}是由数组
 3 {6,5,4,3,2,1}左移两位形成的。写一个程序,实现查找这种数组中的某一个数的功能。
 4 */
 5 
 6 #include<iostream>
 7 #include<string>
 8 #include<cassert>
 9 using namespace std;
10 
11 const int NOT_FOUND = -1;
12 
13 //key为要找的值.
14 int find(int arr[], int len, int key)
15 {
16     assert(arr!=NULL && len >0 );
17 
18     int low = 0;
19     int high = 0;
20     int mid = 0;
21 
22     int max = arr[0];
23     int pos = 0;
24     //找到最大值作为循环数组的起点。
25     for(int i=0; i<len; i++)
26         if(arr[i] > max)
27         {
28             max = arr[i];
29             pos = i;
30         }
31     low = pos;
32     high = (low + len - 1)%len;
33     bool lowLHigh = true;
34 
35     //只有左移0位(即原数组不移动)的情况下,才会有low<high.
36     if(low < high)
37         lowLHigh = true;
38     else
39         lowLHigh = false;
40 
41     bool isFirst = true;
42 
43     //while结束的条件比较复杂.
44     //lowLhigh=true时:即low is in the left of high. 这时的循环跳出条件为low > high.即常规的二分查找的情况.
45 
46     //lowLhigh=false时,即low is in the right of high. 这时的循环跳出条件是low再次等于(high+1)%len(因为
47     //刚开始的时候也是这种情况)。
48     while( (lowLHigh&&low<high) || (!lowLHigh && (isFirst || low!=(high+1)%len )  ) )
49     {
50         isFirst = false;
51         int halfSize = ((high - low + len)%len)/2;
52         mid = ( low + halfSize )%len;
53         if(arr[mid] == key)
54             return mid;
55         else if(arr[mid] < key)
56             high = (mid - 1 + len)%len;
57         else
58             low = (mid + 1 + len)%len;
59     }
60     return NOT_FOUND;
61 }
62 
63 
64 int main()
65 {
66     int arr[] = {6,4,2,0,10,8};
67 
68     //key = [0..10]均通过测试。
69     int key;
70     while(cin >> key)
71     {
72         cout<<find(arr, 6, key)<<endl;
73     }
74     
75     return 0;
76 }
posted @ 2012-07-10 22:17  Frank@609  Views(374)  Comments(0Edit  收藏  举报