在一個排序的數組中,如{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;
}