面试题8:旋转数组的最小值(Leetcode-153,154)

题目:把一个数组最开始的若干元素搬到数组的末尾,称为数组的旋转。
输入一个递增数组的一个旋转,输出其最小值。假设这个递增数组中没有重复元素
例如数组{3,4,5,1,2}是{1,2,3,4,5}的一个旋转,最小值是1。

一. O(N)解法

最直观的解法就是遍历数组,找到一对相邻的数,前数比后数大,则后数就是最小值。
如果未找到这样一对相邻的数,那么这个数组就未旋转,最小值即为第一个数。

int findMin(vector<int>& nums) {
    int size = nums.size();   
    for(int i=1; i<size; ++i)
    {
        if(nums[i] < nums[i-1])
        {
            return nums[i];
        }
    }    
    return nums[0];
}

二. O(logN)解法

显然,这种解法未利用旋转数组的特性,对于旋转数组,最小的数满足以下两个条件:
(1)在一个递减序列中
(2)必定是相邻的两个数之间的小者
(3) 如果未找到递减序列,那么说明数组未旋转,第一个数就是最小数
我们可以用双指针,分别从两边遍历到中间的方法找到这个最小数。分析如下:
在这里插入图片描述

int minNumberInRotateArray(vector<int> a) {
    int i = 0, j = a.size()-1;
    while (i < j) {
      if (a[i] > a[i+1]) {
        return a[i+1];
      }

      if (a[j-1] > a[j]) {
        return a[j];
      }
      ++i;
      --j;
    }
    return a.empty() ? 0 : a[0];
}

三. 旋转数组中存在重复元素(Leetcode-154)

如果旋转数组为{10,1,10,10}。
O(logN)的解法就无法使用了。
只能用第一种O(N)解法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值