题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路: 采用二分法的思想
当由于数组是非递减的,所以将数组前面旋转至数组尾部后,可以将旋转后的数组看成两部分,前后两部分均是非递减的,且前半部分整体大于等于后半部分。所以定义如下:
left代表数组最左侧第一个元素的下标,right代表最右侧最后一个元素的下标,mid取中间值。
(1)当arr[mid]>=arr[left]时,代表最小值在mid的右侧
(2)当arr[mid]<arr[left]时,代表最小值在mid的左侧
(3)arr[mid]==arr[left]且arr[mid]==arr[right]时,无法判断,需要进行线性遍历。
代码如下:
int minNumberInRotateArray(vector<int> rotateArray) {
int left=0;
int right=rotateArray.size()-1;
int mid=0;
if(rotateArray.empty())
{
return 0;
}
while(rotateArray[left]>=rotateArray[right])
{
if(right-left==1)
{
mid=right;
return rotateArray[mid];
}
mid=left+(right-left)/2;
//说明最小数在mid的右侧
if(rotateArray[mid]>=rotateArray[left])
{
left=mid;
}
//说明最小值在mid左侧
else
{
right=mid;
}
//无法判断最小值在左边还是右边,所以线性遍历
if(rotateArray[mid]==rotateArray[left]
&&rotateArray[mid]==rotateArray[right])
{
int result=rotateArray[left];
for(int i=left+1;i<right;i++)
{
if(result>rotateArray[i])
result=rotateArray[i];
}
return result;
}
}
return rotateArray[mid];
}