注意这里数组是不含重复数字的。
考虑数组任意的一次向右滚动(一个单位),最后两个元素A[n-1], A[n-2].
若A[n-1]事实上为最初的A[0], 那么这次滚动后,数组将回到最初的状态,A[0'] < a[(n-1)'], 成为升序数组,二分搜索即可;
若A[n-1]并非最初的A[0], 那么必有A[n-2] <= A[n-1], 滚动后,A[n-1]变成A[0], A[0'] >= A[(n-1)'], 此时应当将数组分成两半,二分递归。
1) 若num[0] < num[n-1], 那么整个数组为升序;
2) 反之,必有一点k, 使得num[0, 1, ..., k]为升序,num[k+1, k+2, ..., n-1]为升序。此时以(left+right)/2为中点,把数组分成两部分,继续递归求解。
代码:
class Solution { public: int search(int A[], int n, int target) { return find(A, 0, n-1, target); } private: int find(int a[], int l, int r, int target) { if (l > r) { return -1; } int index = -1, mid = (l+r)>>1; if (a[l] <= a[r]) { while (l <= r) { mid = (l+r) >> 1; if (a[mid] == target) { index = mid; break; } else if (a[mid] < target) { l = mid + 1; } else { r = mid - 1; } } } else { index = find(a, l, mid, target); index = index!=-1? index: find(a, mid+1, r, target); } return index; } };