把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
牛客网AC代码:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size() == 0){
throw "invalid parameters";
}
int left = 0,right = rotateArray.size()-1;
if(rotateArray[left] < rotateArray[right])
return rotateArray[left];
while(1){
if(right - left == 1)
return rotateArray[right];
int mid = (left + right) / 2;
if(rotateArray[mid] >= rotateArray[left])
left = mid;
else
right = mid;
}
}
};
编程代码如下:
#include<iostream>
using namespace std;
//找出旋转数组最小值
int Min(int arr[],int l,int r);
//找出旋转数组最小值
int MinInOrder(int* numbers, int index1, int index2);
int Min_2(int* numbers, int index1,int index2);
int main(){
int arr[] = {3, 4, 5, 1, 2};
cout<<Min(arr,0,sizeof(arr)/sizeof(int)-1)<<endl;
int arr1[] = {3, 4, 5, 1, 1, 2 };
cout<<Min(arr1,0,sizeof(arr1)/sizeof(int)-1)<<endl;
int arr2[] = { 3, 4, 5, 1, 2, 2 };
cout<<Min(arr2,0,sizeof(arr2)/sizeof(int)-1)<<endl;
int arr3[] = {1, 0, 1, 1, 1 }; //i、j、k相等
cout<<Min(arr3,0,sizeof(arr3)/sizeof(int)-1)<<endl;
// 单调升序数组,旋转0个元素,也就是单调升序数组本身
int arr4[] = { 1, 2, 3, 4, 5 };
cout<<Min(arr4,0,sizeof(arr4)/sizeof(int)-1)<<endl;
int arr5[] = { 2 };
cout<<Min(arr5,0,sizeof(arr5)/sizeof(int)-1)<<endl;
int arr6[] = { 5,4,3,2,1 };
cout<<Min(arr6,0,sizeof(arr6)/sizeof(int)-1)<<endl;
int *arr7 = nullptr;
cout<<Min(arr7,0,0)<<endl;
return 0;
}
int Min(int arr[],int l,int r){
if(arr == nullptr || l > r)
{
try{
throw "输入错误!";
}
catch(const char *s){
cout<<s<<endl;
}
}
int i=l,j=r;
int k = i + (j - i)/2;
if(arr[l] < arr[r])//特殊情况,没有搬任何数字
return arr[l];
if( (arr[k] <= arr[l] && arr[k] > arr[r]) || (arr[k] < arr[l] && arr[k] >= arr[r]))//搬全部的数字
return arr[r];
if(arr[k] == arr[l] && arr[k] == arr[r])//特殊情况,i、j、k相等
{
int min = arr[l];
for(int i=0;i<r;i++)
if(min > arr[i])
min = arr[i];
return min;
}
while(j-i != 1){
k = i + (j - i)/2;
if(arr[k] >= arr[i])
i = k;
else if(arr[k] <= arr[j])
j = k;
}
return arr[j];
}
int MinInOrder(int* numbers, int index1, int index2)
{
int result = numbers[index1];
for(int i = index1 + 1; i <= index2; ++i)
{
if(result > numbers[i])
result = numbers[i];
}
return result;
}
int Min_2(int* numbers, int index1,int index2)
{
if(numbers == nullptr || index1 > index2)
{
try{
throw "输入错误!";
}
catch(const char *s){
cout<<s<<endl;
}
}
int indexMid = index1;
indexMid = (index1 + index2) / 2;
while(numbers[index1] >= numbers[index2])
{
// 如果index1和index2指向相邻的两个数,
// 则index1指向第一个递增子数组的最后一个数字,
// index2指向第二个子数组的第一个数字,也就是数组中的最小数字
if(index2 - index1 == 1)
{
indexMid = index2;
break;
}
// 如果下标为index1、index2和indexMid指向的三个数字相等,
// 则只能顺序查找
indexMid = (index1 + index2) / 2;
if(numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1])
return MinInOrder(numbers, index1, index2);
// 缩小查找范围
if(numbers[indexMid] >= numbers[index1])
index1 = indexMid;
else if(numbers[indexMid] <= numbers[index2])
index2 = indexMid;
}
return numbers[indexMid];
}
运行结果如下: