假定一个有序数组中的元素以某个支点做了旋转,如数组01234567变成了34567012,查找该旋转后数组中的最小值。
算法思路:
旋转后数组被分为了两部分,较大的一部分和较小的一部分并且较小的一部分在后面,如果我们取中间(非两头)的一个元素c,那么它相对于第一个a和最后一个元素b有如下关系:
c < a , c < b => 最小元素在a-c之间
c > a , c > b => 最小元素在c-b之间
c = a , c = b => 最小元素在a-c之间
用二分法实现代码如下:
#include <iostream>
#include <vector>
// 二分法实现 O(log2n)
bool find_min_in_rotate_sorted_array(const std::vector<int>& array, int& value) {
if (array.size() == 0) {
return false;
}
int low = 0, high = array.size() - 1;
int mid = (high + low) / 2;
while (low < high) {
mid = (high + low) / 2;
if (array[mid] < array[low]) {
if (high == mid) {
high = low;
} else {
high = mid;
}
} else if (array[mid] > array[high]) {
if (low == mid) {
low = high;
} else {
low = mid;
}
} else {
high = mid;
}
}
value = array[low];
return true;
}
int main(int argc, char** argv) {
std::vector<int> array = {2, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
int value;
if (find_min_in_rotate_sorted_array(array, value)) {
std::cout << value << std::endl;
}
return 0;
}
注意:以上代码请使用c++11编译