problem:
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.
这道题如果顺序查找,就没啥意思了。下面分析一下二分查找法的使用。
首先找到pivot的位置,pivot指的是顺序序列中的最大值,可以观察得到,若用二分法查找,比较中间mid位置与队首pre位置的值比较,若大于队首,说明pivot在mid与target之间,修改pre的位置;若小于pre上的值,说明pivot在pre与mid之间,修改post的值。
找到pivot的位置之后,比较target与pre的值,若小于pre,则target在pivot到post之间,若大于pre,说明在pre与pivot中间。
对对应情况进行二分查找即可。
class Solution {
private:
int FindPivot(vector<int> nums)
{
int result = -1;
int mid = -1;
int length = nums.size();
int pre = 0;
int post = length - 1;
//序列有序
if(nums[length-1] > nums[0])
result = -1;
else
{
//序列无序,二分查找旋转点
while(pre<=post)
{
mid = (pre + post) / 2;
//若pivot在mid后面
if(nums[mid] > nums[pre])
pre = mid;
else if(nums[mid] < nums[pre])
post = mid;
else
{
result = mid;
break;
}
}
}
return result;
}
//二分法
int binaryfind(int pre, int post, int target, vector<int> nums)
{
int result = -1;
while(pre<=post)
{
int mid = (pre + post) / 2;
if(nums[mid] > target)
post = mid - 1;
else if(nums[mid] < target)
pre = mid + 1;
else
{
result = mid;
break;
}
}
return result;
}
public:
int search(vector<int>& nums, int target) {
int result;
int pivot;
int length = nums.size();
//寻找转折点
pivot = FindPivot(nums);
if(pivot == -1)
result = binaryfind(0, length-1, target, nums);
else if(nums[0] > target)
result = binaryfind(pivot+1, length-1, target, nums);
else
result = binaryfind(0, pivot, target, nums);
return result;
}
};