题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
代码及分析如下:
<span style="font-size:18px;">#include<iostream>
using namespace std;
//顺序查找最小数字
int SequenceSelect(int* arr, int left, int right)
{
if (arr == NULL || left < 0 || right < 0 || left > right)
return -1;
int min = arr[left];
for (left=left + 1; left < right; ++left)
{
if (min > arr[left])
min = arr[left];
}
return min;
}
//利用二分查找和旋转数组的特性
//旋转数组被分为俩个递增数组
//1.arr[0] < arr[len-1];数组没有旋转,最小值为arr[left]
//2.arr[0]>arr[len-1];中间元素在前面的递增数组,还是后面的递增数组
//(1).arr[mid] < arr[right];在前面的递增数组
//(2).arr[mid] > arr[left];在后面的递增数组里
//最终left会指向第一个递增数组的末尾,right会指向递增数组的开头
//3.特例:当不能使用二分查找时(arr[left] = arr[right] = arr[mid]),需要用顺序查找法
int TurnArrMinNum(int* arr, int len)
{
if (arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
int mid = 0;
if (arr[left] < arr[right])
{
arr[mid]v7f8 = arr[left];
}
while (arr[left] >= arr[right])
{
if (right - left == 1)
{
mid = right;
break;
}
mid = left + (right - left) / 2;
if (arr[left] == arr[right] && arr[left] == arr[mid])
{
//顺序查找
int min = SequenceSelect(arr, left, right);
return min;
}
if (arr[mid] > arr[left])
{
left = mid;
}
else if (arr[mid]< arr[right])
{
right = mid;
}
}
return arr[mid];
}
//测试用例:
int main()
{
int arr[5] = { 3, 4, 5, 1, 2 };
int min = TurnArrMinNum(arr, sizeof(arr) / sizeof(arr[0]));
cout << "min:" << min << endl;
int arr1[5] = { 1, 0, 1, 1, 1 };
min = TurnArrMinNum(arr1, sizeof(arr1) / sizeof(arr1[0]));
cout << "min:" << min << endl;
int arr2[5] = { 1, 1, 1, 0, 1 };
min = TurnArrMinNum(arr2, sizeof(arr2) / sizeof(arr2[0]));
cout << "min:" << min << endl;
return 0;
}</span></span>