把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
直接进行数组遍历的话,时间复杂度是O(n)。
对于本题可以使用二分法搜索,因为旋转数组是对原本递增的数组进行旋转,每次我们需要根据首、尾和中间元素进行判定,判断最小元素在哪个区间,缩小搜索范围,时间复杂度为O(logn).
public :
int BinarySearch(vector<int> arr, int start, int end)
{
int i = 0;
int mid = (start + end + 1) / 2;
int res1 = 0;
int res2 = 0;
if (start == end)
{
return arr[start];
}
/* 只剩两个元素 */
if (start == end - 1)
{
return (arr[start] < arr[end]) ? arr[start] : arr[end];
}
/* 没有旋转过的数组 */
if (arr[start] < arr[end])
{
return arr[start];
}
/* start = mid = end
该情况,无法判定最小元素位于哪个区间,两个区间分别查找,返回较小值
*/
if (arr[mid] == arr[start] && arr[mid] == arr[end])
{
res1 = BinarySearch(arr, start, mid-1);
res2 = BinarySearch(arr, mid+1, end);
return (res1 < res2) ? res1 : res2;
}
else
{
/* 最小元素在二分的右边 */
if (arr[mid] >= arr[start] && arr[mid] >= arr[end])
{
return BinarySearch(arr, mid+1, end);
}
/* 最小元素在二分的左边 */
else
{
return BinarySearch(arr, start, mid);
}
}
}
public:
int minNumberInRotateArray(vector<int> rotateArray)
{
int i = 0;
int res = 0;
int size = rotateArray.size();
int start = 0;
int end = size - 1;
if (rotateArray.size() == 0)
{
return 0;
}
res = BinarySearch(rotateArray, start, end);
return res;
}