在一个排序的数组中,如{1,2,3,4,5,6,7},经过旋转后得到{4,5,6,7,1,2,3},当然也可以得到原数组{1,2,3,4,5,6,7},在该旋转后的数组中查找某个元素。
陷阱在于数组不是严格递增的
比如{1,1,1,1,0,1,1}这样有很多重复的元素的数组时,当要查找0时,在mid位置的元素为1,不能判断怎么缩小范围
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
#define debug_
int find_rotate(vector<int>& vec,int left,int right,int value)
{
if (vec.empty() || left > right)
return -1;
int mid(0);
while (left + 1 < right)
{
mid = left + ((right - left) >> 1);
if (vec[mid] == value)
{
return mid;
}
//首先考虑mid、left、right中有相同值的情况
//因为如果有相同值,无法判断二分查找的方向,且不好分类讨论
if (vec[right] == vec[left])
{
left++;
continue;
}
if (vec[mid] == vec[left])
{
left = mid;
continue;
}
if (vec[mid] == vec[right])
{
right = mid;
continue;
}
//此时mid、left、right都不相同
if (vec[mid]>vec[left]&&vec[mid]>vec[right] )
{
if (value>vec[mid]|| value<=vec[right] )
{
left = mid;
}
else
{
right = mid;
}
}
else
{
if (value>vec[left]||value<vec[mid])
{
right = mid;
}
else
{
left = mid;
}
}
}
if (vec[left]==value)
return left;
else if (vec[right] == value)
return right;
else
return -1;
}
int main()
{
vector<int> vec{ 1, 1, 1, 1, 1, 2, 1 };
vector<int> vec_2{ 2, 1, 1, 1, 1, 1, 1 };
vector<int> vec_3{ 2, 0, 1, 1, 1, 1, 1 };
cout << find_rotate(vec, 0, vec.size() - 1, 2)<<endl;
cout << find_rotate(vec_2, 0, vec_2.size() - 1, 2)<<endl;
cout << find_rotate(vec_3, 0, vec_3.size() - 1, 0)<<endl;
return 0;
}