旋转数组的最小数字

剑指offer第11道题:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

刚开始读题,一遍都没读懂(我是小白,才开始入门),再读一遍,题目的目的不就是求出一个在一个数组中的最小值,如果数组大小为0,则返回0

第一次思路:

于是我就一下子想用暴力来解决这道题,遍历这个数组,用一个指针来指最小值,每次如果比这个指针的值小就更新为最小,直到遍历完整个数组得到最小值,不用说时间复杂度是0(n)

再一想这道题也没有这么简单,再读读题目,发现题目中的非递减排序的数组,有这么个条件我们没有用到,我们来看example:

对于数组3,4,5,1,2,这个数组是由两个子数组345和12交换位置得来的,原数组12345,又发现交换后,前面的数组中的值都比后面的数组中的值小,而我们要找的这数字肯定在这两个数组交界处,所以没有可能必要遍历完整个数组,当然存在其他情况,稍后补充

第二次思路:

我们通过二分思想来解决这道题

在数组中定义两个指针下标l和r,同时定义一个mid下标指针,这个指针用来缩小l和r的范围,从而确定出最小值

对于这个数组,如果mid下标指的值比r下标指的值大,说明mid在左边的数组中,进一步我们挪动l到mid处,下一次新的l到r遍历范围缩小

如果mid下标的值比l下标的值小,说明mid在右边的数组中,在这个栗子中,5比3大说明,在345这个数组中

不断的缩小遍历范围,我们最终找到那个最小值,代码思路如下:

public class Solution {
    public int minNumberInRotateArray(int array[]){
        if(array.length==0){
            return 0;
        }
        int l=0;
        int r=array.length-1;
        while(l<r-1){
            int mid=(l+r)>>1;
            if(array[mid]>=array[l]){//如果中间的值大于左边的值,说明mid的下标在第一个左子数组上
                l=mid;
            }else if(array[mid]<=array[r]){//如果中间的值小于右边的值,说明mid的下标在右边的子数组上
                r=mid;
            }
        }
        return array[r];
    }
}

时间复杂度是0(logn)

为什么这里的比较条件是array[mid]>=array[l],没有等号行吗,如果没有等号对于3,2,2,2,2,这样的栗子,while循环就一直出不去

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值