题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。**
首先在拿到这道题的时候,自己的第一反应是把12345变成34512,然后才发现题目要求的是求出最小值,而给你的数列是一个翻转数列,他原来的数列是有序的;
但是不妨碍有相同的元素
所以我们要想到有两种情况的发生;
我们要求出最小值,所以不可避免的要进行查找,我们这里采用效率最高的也是面试常考的二分查找;
定义数组的长度
int size=array.size();
然后我们要进行二分查找
int left=0;
int right=size-1;
int mid=(left+right)/2
定义完数组,我们要进行查找,情况分为:
/*如果第一个元素和最后一个元素重复相等 eg:1 1 1 0 1*/
array[left]==array[right];
这个时候我们就需要一遍一遍的去遍历整个数组
int orderFind(vector<int> array, int left, int right)//找出最小值 最左边的=最右边的
{
int min = array[left];//假设第一个数为最小数
for (int i = left + 1; i <= right; i++)
{
if (array[i] < min)
min = array[i];
}
return min;
}
然后第二种情况就是
if (right - left == 1)//可以判断出有三个数 2 3 1
{
// 最小的就是右边
mid = right;
break;
}
第三种情况:
//如果最左边小于等于中间,说明最小值在后半部分2 3 4 5 1
else if(Array[mid]>=Array[left])
{
left=mid;
}
//如果最右边的大于中间,说明最小值在前半部分7 1 2 3 4 5 6
else if(Array[mid]<=Array[right])
{
right=mid;
}
整体的源代码:
int orderFind(vector<int> array, int left, int right);
class Solution {
public:
int minNumberInRotateArray(vector<int> Array) {
int size=Array.size();
if(size==0)
{
return 0;
}
int left=0;
int right=size-1;
int mid=(left+right)/2;
while(Array[left]>=Array[right])
{
// 如果此时数组只剩下两个数值
if (right - left == 1)
{
// 最小的就是右边
mid = right;
break;
}
// 如果数组长度是2个以上
mid = (left + right) / 2;
// 假如最左边和中间以及最右边值都相等,只能进行顺序查找,如{1,1,1,0,1}
if (Array[left] == Array[mid] && Array[left] == Array[right])
{
return orderFind(Array, left, right);
}
//如果最左边小于等于中间,说明最小值在后半部分
else if(Array[mid]>=Array[left])
{
left=mid;
}
else if(Array[mid]<=Array[right])
{
right=mid;
}
}
return Array[mid];
}
};
int orderFind(vector<int> array, int left, int right)
{
int min = array[left];
for (int i = left + 1; i <= right; i++)
{
if (array[i] < min)
min = array[i];
}
return min;
}