Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
对于二分法的一个拓展,几个注意点:
1.利用位运算来表示除法时,注意优先级,位运算优先级较低,是低于四则运算的,如本题中mid = left + (right - left) / 2; 一开始用位运算 mid = left + (right - left) >> 1, 一直TL,后来才想起来这个实际上是算的 (left + (right - left)) >> 1;
2.这里关键是有个转折点,在使用二分法的同时,应该考虑到这个转折点,ex:7 8 9 10 1 2 这个转折点(也是这个序列的最大值处)就是10,不含转折点的那部分就是一个严格的升序排列序列,可以直接用二分法求target,而包含的那一个还需要加一个判断;
3.再利用已经判好序的部分的头尾元素表示了整个范围这个特性,进行分部选取;
代码如下:
class Solution {
public:
int search(int A[], int n, int target) {
if (A == NULL || n == 0)
return -1;
int left = 0, right = n - 1, mid = 0;
while (left <= right){
mid = left + (right - left) / 2;
if (A[mid] == target)
return mid;
else if (A[mid] > A[right]){ //转折点在右边部分,这样左边部分是升序排列的
if (A[left] <= target && target < A[mid]) //满足这个条件就进入了没有转折点、全部都是升序的序列
right = mid - 1;
else
left = mid + 1;
}
else{ //这里表示转折点在左边或者已经没有转折点了,既已经进入了完全升序的序列
if(A[mid] < target && target <= A[right])
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}
};