假定一个有序数组中的元素以某个支点做了旋转,如数组01234567变成了34567012,查找该旋转后数组中的最小值。
算法思路:
旋转后数组被分为了两部分,较大的一部分和较小的一部分并且较小的一部分在后面,如果我们取中间(非两头)的一个元素c,那么它相对于第一个a和最后一个元素b有如下关系:
c < a , c < b => 最小元素在a-c之间
c > a , c > b => 最小元素在c-b之间
c = a , c = b => 缩小查找范围
用二分法实现代码如下:
#include <iostream>
#include <vector>
using namespace std;
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.size() == 0) {
return 0;
}
int start = 0;
int end = rotateArray.size() - 1;
while (start < end) {
int left = rotateArray[start];
int right = rotateArray[end];
int mid = (end + start) / 2;
if (rotateArray[mid] > left || rotateArray[mid] > right) {
start = mid;
}
if (rotateArray[mid] < right || rotateArray[mid] < left) {
end = mid;
}
if (rotateArray[mid] == left) {
while (++start < end && rotateArray[start] == left);
if (start == end) {
start;
break;
}
}
if (rotateArray[mid] == right) {
while(start < --end && rotateArray[end] == right);
if (start == end) {
start;
break;
}
}
}
return rotateArray[start];
}
int main()
{
std::vector<int> rotateArray = {2, 2, 2, 1, 2};
cout << minNumberInRotateArray(rotateArray) << endl;
return 0;
}
注意:以上代码请使用c++11编译