https://www.cnblogs.com/grandyang/p/4325840.html
https://www.cnblogs.com/grandyang/p/4325648.html
https://www.cnblogs.com/grandyang/p/4032934.html
1.无重复数字时
无重复有序数组{1,2,3,4,5,6},
它的一个旋转组{4,5,6,1,2,3}。
元素5在旋转数组内,返回下标1
元素7不在旋转数组内,返回-1
根据上图,发现旋转数组mid左右必然有一个有序;
在有序的半边数组二分查找,如果找不到,跳到另一半去找;
接下来在新区间重复mid左右又有一个是有序的过程。
#include <iostream>
#include<vector>
using namespace std;
int search(vector<int>& v,int num)
{
int left=0;
int index=-1;
int right=v.size()-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(v[mid]==num)
{
return mid;
}
if(v[left]<v[mid])//左边(包含mid)有序
{
if(num<v[mid] && num>=v[left])
right=mid-1;
else
left=mid+1;
}
else//右边(包含mid)有序
{
if(num>v[mid] && num<=v[left])
left=mid+1;
else
right=mid-1;
}
}
return index;
}
int main()
{
vector<int> v={4,5,6,1,2,3};
cout<<search(v,2);
}
2.有重复数字时
稍作改动,左侧游标移动跳过重复的数字
#include <iostream>
#include<vector>
using namespace std;
int search(vector<int>& v,int num)
{
int left=0;
int index=-1;
int right=v.size()-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(v[mid]==num)
{
return mid;
}
if(v[left]<v[mid])//左边(包含mid)有序
{
if(num<v[mid] && num>=v[left])
right=mid-1;
else
left=mid+1;
}
if(v[left]>v[mid])//右边(包含mid)有序
{
if(num>v[mid] && num<=v[left])
left=mid+1;
else
right=mid-1;
}
if(v[left]==v[mid])//有重复数字时
left++;
}
return index;
}
int main()
{
vector<int> v={6,6,2,3};
cout<<search(v,2);
}