offer6旋转数组找最小元素

感谢  链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba?answerType=1&f=discussion
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
针对的目标待处理数组是下面这样的

下图中上面的曲线可以看做原数组,从竖线处切分后,得到下面的图。我们的目标就是找那个最低点。


/**
* 第一种做法,通过题意可以了解到,只需要输出旋转后数组最小元素就行了,所以直接给数组进行排序。
a. 可以使用Java内置的排序方法,数组的第一个元素就是最小元素,最后输出即可,Arrays.sort()的排序时间复杂度是根据数组长度来判断,这个内置排序的 基本类型是quick sort快速排序,对象类型是优化过后 merge sort合并排序,时间复杂度是O(nlgn) 空间复杂度O(1)
b.也可以使用二分排序等自己写的排序方法

*/
publicintminNumberInRotateArray(int[] array) {
if(array.length ==0|| array ==null)return  0;
Arrays.sort(array);
return  array[0];
}
感谢  链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba?answerType=1&f=discussion
来源:牛客网


  • 3 4 5 1 2 (一般情况)
  • 1 2 3 4 5 / 2 2 2 2 2(容易想到的点)
  • 1 0 1 1 1 / 1 1 1 0 1(特例)

直接进行顺序的查找,复杂度为O(n).
但是我们看到题中是给出的有序的旋转数组,我们可以采用二分法来进行求解,其复杂度为O(logn).
这里我们需要利用带有条件的二分法来进行求解:

第一步我们可以将这个旋转的数组看作是前后两个有序的子数组,然后设定我们的中间值 mid = (start + end) // 2.

第二步我们能够看到,当我们选取的中间值 mid 所对应的值大于 start 所对应的值时,说明此时 mid 还在第一有序的数组中,而我们所要求解的最小值是在第二个有序数组的第一个位置,此时也就是在 mid 的后面,我们就将 start 移到 mid 所在的后一个元素的位置.

第三步,当我们的 end 所对应的值大于 mid 所对应的值时,说明最小值可能是 mid 所对应的值或者在 mid 的前面,我们将 end 移到 mid 所在的位置.

第四步,最后我们的 end 所在的位置就是最小值的位置,直接返回即可.
有这样的特例 比如数组 10111 , 这是会出现当 start mid end 所对应位置的值相等,这时候我们的程序就不能找到最小值,当出现这样的情况是 我们采用将 start 和 end 区间里面的值进行顺序查找来找出最小值.
--------------------
链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba?answerType=1&f=discussion
来源:牛客网

二分查找变种,没有具体的值用来比较。那么用中间值和高低位进行比较,看处于递增还是递减序列,进行操作缩小范围。

  • 处于递增:low上移

  • 处于递减:high下移(如果是high-1,则可能会错过最小值,因为找的就是最小值)

  • 其余情况:low++缩小范围
    图片说明

  • 特殊情况:图片说明

代码:
public int minNumberInRotateArray(int [] array) {
//Arrays.sort(array);
//数组为空的情况
if(array.length ==0|| array ==null)
return 0;
//数组中只有一个元素
if(array.length ==1)
return array[0];
//数组包含两个及其以上元素的情况,使用二分查找算法实现
//利用好非递减排序的数组这个性质,显然,这是一个局部排好序的列表
//循环终止条件:区间长度为1
int low =0;
int high = array.length -1;
int mid =0;
while(low < high){
// 子数组是非递减的数组,10111
if(array[low] < array[high])
return array[low];
mid = low + (high - low) /2;
if(array[mid] > array[low])
low = mid +1;
else if(array[mid] < array[high])
high = mid;
else low++;
}
return array[low];


}



#旋转数组二分法变种##笔试题目#
全部评论

相关推荐

10-13 22:56
门头沟学院 C++
rt,鼠鼠的浪潮网签明天过期,鼠鼠是山东人,好像自己也能接受。之前的面试大厂基本挂干净了,剩下小米二面后在泡,问了下面试官没有挂,但要泡。还有海信似乎也通过了,不过在深圳,鼠鼠也不是很想去。其它还有一些公司应该陆陆续续还有一些面试,现在有些纠结是直接签了还是再等再面呢?大佬们能不能给鼠鼠提一些意见,万分感谢!!!
牛客78696106...:浪潮可不是开摆,当初我还是开发的时候我组长跟我说他们组有段时间天天1,2点走,早上5点就来,全组肝出来心肌炎,浪潮挣钱省立花可不是说说,当然也看部门,但是浪潮普遍就那dio样,而且你算下时薪就知道不高,没事也是9点半走,不然算你旷工
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
野猪不是猪🐗:还是太卑微了,什么叫放弃本次面试应该说经过评估,贵公司与自己不匹配,决定不再推进后续流程
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务