题目描述:
将一个数组最开始的若干元素搬到数组的末尾,称之为旋转数组;输入一个增序数组的旋转数组例如{3,4,5,1,2} 其旋转数组中的最小数值为{1};
思路一:
顺序遍历数组中的每一个元素,找出最小值;时间复杂度O(n);
思路二:
旋转数组有增序数组变换而来,可以考虑二分查找 , 其复杂度为O(logN);
但是旋转数组的增序排列是分为两部分的,而且我们的目标:最小值,正好为量子数组的分界线;
例如{3 ,4 ,5} ,{1 ,2};分界点:最小值1;
依据二分查找的思想,指针start 指向左边数组的首元素:3 ,指针end 指向右边数组的末尾元素:2
指针middle = (start + end) / 2;
正常情况:
若data[middle] >= data[start]:说明最小值在middle之后,start = middle;
若data[middle] <= data[emd]:说明最小值在middle之前(包括middle) , end = middle;
当end - start == 1,即start ,end相邻时:minNumber = data[end];
特殊情况:
旋转位数为0;递增数组未翻转;那么此时的最小值 minNumber = data[start]; {1,2,3,4,5}--》{1}
当大部分数组元素相等时:{2 ,1, 2, 2,2,2} , {2 , 2 , 2 , 2 , 1 , 2};
data[start] = data[middle] = data[end];可以在利用顺序遍历的思想;
代码实现:
#include<iostream>
#include<exception>
using namespace std;
//---------------------------------------------旋转数组的最小数字---------------------------------------
int MinInorder(int* data , int start , int end);
int MinNumber(int* data , int length)
{
if(data == NULL || length <= 0)
throw new std::exception("Invalid parameters");
int start = 0;
int end = length - 1;
//确保旋转位数为0,首部元素最小;
int middle = start;
while(data[start] >= data[end])
{
//start end相邻;
if(end - start == 1)
{
middle = end;
break;
}
middle = (start + end) / 2;
if(data[middle] >= data[start]) //minNumber 在后半部
start = middle;
else if(data[middle] <= data[end]) //minNumber 在前半部
end = middle;
//*start ,*middle ,*end 三者相等--》顺序遍历
if(data[start] == data[middle] && data[middle] == data[end])
return MinInorder(data , start , end);
}
return data[middle];
}
//顺序遍历
int MinInorder(int* data , int start , int end)
{
int minNumber = data[start];
for(int i = start + 1; i <= end; ++i)
{
if(minNumber > data[i])
minNumber = data[i];
}
return minNumber;
}
//---------------------------------------------------------------------------------------------------------------
int main()
{
int data1[] = {3 , 4 , 5 , 1 , 2};
cout<<MinNumber(data1 , sizeof(data1) / sizeof(int))<<'\n';
int data2[] = {1 , 2 , 3 , 4 , 5};
cout<<MinNumber(data2 , sizeof(data2) / sizeof(int))<<'\n';
int data3[] = {3 , 4 , 5 , 5 , 1 , 2};
cout<<MinNumber(data3 , sizeof(data3) / sizeof(int))<<'\n';
int data4[] = {3 , 4 , 5 , 1 , 1 , 2};
cout<<MinNumber(data4 , sizeof(data4) / sizeof(int))<<'\n';
int data5[] = {1 , 1 , 1 , 1 , 1 , 1};
cout<<MinNumber(data5 , sizeof(data5) / sizeof(int))<<'\n';
cout<<MinNumber(NULL , 0)<<'\n';
return 0;
}