题目链接:旋转数组的最小数字
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
题目要求给一个非递减排序的数组的一个旋转,需要输出旋转数组的最小元素,我们可以直接进行遍历去找最小的那个数,但是这种方法肯定是效率最低的
核心考点:数组理解,二分查找,临界条件
方法一思路:
一个非递减的数组左旋之后,最开始出现递减的地方的那个数字就是最小值,我们可以比较相邻的两个数,如果右边的数小于左边的数,那么该右边的这个数字就是最小值,这种方法本质上和上面的没有区别,效率不高
方法二思路:
定义首位下标,因为是非递减数组旋转,所以旋转最后可以看作成两部分,前半部分整体非递减,后半部分整体非递减,前半部分整体大于后半部分。当a[mid]大于等于a[left]时,说明mid属于原数组前半部分,目标最小值,在mid的右侧,让left = mid;当a[mid]小于a[left],说明mid位置在原数组后半部分,说明目标最小值在mid的左侧,让right = mid。
方法二解题代码:
class Solution
{
public:
int minNumbeiInRotateArray(vector<int> array)
{
if(array == nullptr||array.size() == 0)
{
return 0;
}
int left = 0;
int right = array.size()-1;
int mid = 0;
while(left<right)
{
//当right和left相邻时,右边的值是
if(right - left==1)
{
mid = right;
break;
}
//如果这三者相等,没有办法判断左半部分还是右半部分
if(arrar[left] == array[right] && arrar[left] == array[mid])
{
//此时遍历式的去找
int result = array[left];
for(int i = left+1;i<right;i++)//i不用等于right,因为right是和left相等的不用比较
{
if(result>arrar[i])
{
result = array[i];
}
}
return result;
}
mid = (right+left)>>1;
if(array[mid]>=array[left])
{
//当a[mid]大于等于a[left]时,说明mid属于原数组前半部分,目标最小值,在mid的右侧
left = mid;
}
else
{
//当a[mid]小于a[left],说明mid位置在原数组后半部分,说明目标最小值在mid的左侧
right = mid;
}
}
return array[mid];
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/attemptendeavor/article/details/122443909
内容来源于网络,如有侵权,请联系作者删除!