题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路
就很简单,首先判断数组为零,其次依次遍历,如果遇到前一个小于等于后一个,很正常;如果遇到前一个大于后一个,则不正常,返回后一个的值。
这个思路大概是最简单的 复杂度为O(n),代码如下
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0) return 0;
for(int i=0;i<rotateArray.size();i++)
{
if(rotateArray[i]<=rotateArray[i+1])
continue;
else
return rotateArray[i+1];
}
return rotateArray[0];
}
};
看了一下别人的思路,主要是考虑了旋转数组的性质,为两个递增的数组合并结果,这样的,可以分别使用二分法查找,这样的话,时间复杂度为O(logn)。代码如下
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int size = rotateArray.size();
if(size == 0) return 0;
int left = 0,right = size - 1;
int mid = 0;
// rotateArray[left] >= rotateArray[right] 确保旋转
while(rotateArray[left] >= rotateArray[right])
{
// 分界点
if(right - left == 1)
{
mid = right;
break;
}//if
mid = left + (right - left) / 2;
// rotateArray[left] rotateArray[right] rotateArray[mid]三者相等
// 无法确定中间元素是属于前面还是后面的递增子数组
// 只能顺序查找
if(rotateArray[left] == rotateArray[right] && rotateArray[left] == rotateArray[mid])
{
return MinOrder(rotateArray,left,right);
}//if
// 中间元素位于前面的递增子数组
// 此时最小元素位于中间元素的后面
if(rotateArray[mid] >= rotateArray[left])
{
left = mid;
}//if
// 中间元素位于后面的递增子数组
// 此时最小元素位于中间元素的前面
else
{
right = mid;
}//else
}//while
return rotateArray[mid];
}
private:
// 顺序寻找最小值
int MinOrder(vector<int> &num,int left,int right)
{
int result = num[left];
for(int i = left + 1;i < right;++i){
if(num[i] < result){
result = num[i];
}//if
}//for
return result;
}
};