剑指offer第6题:旋转数组的最小数字

题目描述

旋转数组的最小数字

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

分析

顺序查找、二分查找

思路一:非递减数列的含义是对任意位置而已,a[k]<=a[k+1] (0<=k<n).那么对于旋转数组而言,若只要存在两个数时不等的,假设a[min]是最小值首次出现的位置,那么必然有a[min]<a[min-1],而对于其他全部位置有a[k]>=a[k-1].
若从左往右逐个查找,此方法的时间复杂度为O(n).
思路二:利用左右指针:
left指向数组左端,right指向数组右端,取mid = (left+right)/2;
比较a[mid] 与a[left] 的大小:此时有三种情况:

1.a[mid] == a[right] 。
此时并不好缩小数组,例如[1,1,0,1,1],可以将right左移一位,即
right -=1;
2.a[mid] > a[right]。
说明此时最小值在mid的左侧,故使left =mid,以缩小范围。
3.a[mid] < a[right]
说明此时最小值在left与mid之间,有可能就是mid,所以使right= mid 以缩小范围。
当left = right 时,跳出循环,此时两指针同时指向最小值。
思考时间复杂度,一般情况下,若数组中不含相同的数,那么复杂度在o(logN),若数组的元素完全相同,那么复杂度可能高达o(n)。具体用时要看数组中相同元素的个数了。

源码

顺序查找源码

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if (rotateArray.empty()) return 0;
        else{
            for(int ind =0;ind<rotateArray.size()-1;ind++){
                if(rotateArray[ind]>rotateArray[ind+1])
                    return rotateArray[ind+1];
            }
        return rotateArray[0];
        }
    }
};

二分查找源码

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
     vector<int> & a=rotateArray;
      if(a.empty()) return 0;
      int l=0;
      int r=a.size()-1;
      while(l<r)
      {
          int m = (l+r)/2;
          if(a[m]<a[r]) r = m;
          else if(a[m] ==a[r])
          {
             r--;
          }
          else
          {
              l = m+1;
          }
      }
        return a[l];
     }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值