在旋转数组中找最小的值

个人博客传送门

题目描述

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

思路

本题最简单的做法就是从头到尾的遍历。这样一定可以得到结果,只是这样操作的时间复杂度是O(n)。没有利用上旋转这个题目特性。正确的思路是,利用二分查找的思想。让一个begin下标表示数组的开始,一个end下标表示数组的结束,mid表示数组的中间值。通过三者值的比较得到范围。如果mid的值大于begin的值,说明最小值的范围在mid到end之间。反之在begin到mid之间。依次缩小范围,直到找到最小值。

注意

1、存在一种情况,并没有旋转。也就是数组的第一个元素就是最小值。可以通过比较一开始begin和end的值判断,如果begin的值小于end的值,那么直接返回begin的值即可。
2、判断停止的条件是当begin的下一个值就是end的时候,这个时候end一定是最小值。因为begin已经到达最大值,end自然是最小值了。
3、判断的时候请注意重复值的情况。如果出现一种情况,begin、mid、end对应的值都一样。这个时候就需要用遍历的思路来执行查找。
4、需要注意边界值的判断,如果边界值的判断出问题,可能会出现死循环。

代码

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size() == 0)
            return 0;
        int size = rotateArray.size();
        int begin = 0;
        int end = size - 1;
        int mid = 0;

        while(rotateArray[begin] >= rotateArray[end]){
            if(begin+1 == end){
                mid = end;
                break;
            }
            mid = begin + (end-begin)/2;
            if(rotateArray[mid] == rotateArray[begin] &&
               rotateArray[mid] == rotateArray[end])
                return MinNumber(rotateArray, begin, end);
            else if(rotateArray[mid] >= rotateArray[begin])
                begin = mid;
            else if(rotateArray[mid] <= rotateArray[end])
                end = mid;
        }
        return rotateArray[mid];
    }
    int MinNumber(const vector<int>& arr, int begin, int end){
        int result = begin;
        for(int i = result+1; i <= end; ++i){
            if(arr[i] > arr[result])
                break;
            result = i;
        }
        return arr[result];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值