《剑指offer》c++版本 11. 旋转数组的最小数字

如题:

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

题意就是数组中查找最小值,最直接的方法就是排序后得到最小值,但是题目已经指明,数组为非递减数组。有序数组查找一个数,显然用二分法。这题最好的方法就是二分法,虽然暴力遍历找最小值也可以,但是既然有序了,何必画蛇添足。

仔细观察旋转有序数组,二分之后,必有一半是有序的,另一半可能是无序,也可能是有序(没有旋转)。比较方法就是取中值,和首尾比较即可。对于有序数组,左边界即为最小值,对于无序数组,继续递归二分,返回最小值。

此外,编码的时候,注意边界,比如数组为空,取中值不要用 mid = (start+end)/2 的方式,极端情况下整型溢出,最好用

mid = start+(end-start)/2;

下面是本题的c++编码:


//普通解法就是遍历数组查找最小值。
//此题的一个条件是递增数组,有序数组中查找一个数最好的方法是二分法
//二分查找,如果数组有序,返回最小值,如果无序则继续二分。
class Solution {
public:
    int getMinInArray(vector<int> &Array,int start, int end)
    {
        int min1, min2;
        
        //边界判断
        if (start > end)
            return INT_MAX;
        if (start == end)
            return Array[start];
        
        //取中值
        int mid = (end-start)/2 + start;
        
        //有序数组
        if (Array[start] <= Array[mid])
        {
            min1 = Array[start];
            if (Array[mid+1] <= Array[end])
                min2 = Array[mid+1];
            else
            {
                //无序数组继续二分
                min2 = getMinInArray(Array, mid+1, end);    
            }
        }
        else
        {
            //无序数组继续二分
            min1 = getMinInArray(Array, start, mid);
            min2 = Array[mid+1];
        }
        return min1 > min2 ? min2 : min1;
    }
    
    int minNumberInRotateArray(vector<int> rotateArray) {
        int min, len = rotateArray.size();
        vector<int> &rVec = rotateArray;
        //特殊情况处理
        if (rotateArray.size() < 1)
            return 0;
        
        return getMinInArray(rVec,0, len-1);
    }
};

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值