在左移递减数组中查找其中的某一个数(微软面试题)
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 }
多学习,多总结。