• (剑指Offer)面试题8:旋转数组的最小数字


    题目:

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

    输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。

    例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

    思路:

    1、遍历数组,找到数组的最小值,时间复杂度O(n);

    2、二分查找,时间复杂度O(logn)

    注意旋转数组的循环不变量,A[left]>=A[right](这道题的数组为非递减数组,并非严格的递增数组)

    特例:无旋转情况以及{0,1,1,1,1,1}旋转数组

    查找过程:

    旋转数组可以看成两个递增(非减)数组,通过前后两个指针left,right分别指向数组的首尾,

    当满足循环不变量时A[left]>=A[right],mid=(left+right)/2,

    如果A[mid]>=A[left],说明最小值存在mid后面部分,left=mid;

    如果A[mid]<=A[left],说明最小值存在mid前面部分,right=mid;

    经过循环之后,最终left会指向第一个递增数组的最后一个数,right会指向第二个递增数组的第一个数,即最小值mid=right。

    最终return A[mid];

    解决特例问题:

    • 无旋转数组:数组就是递增的,返回第一个数,即A[left],因此mid=left即可;
    • {0,1,1,1,1,1}类似旋转数组:不满足上述查找过程,只能遍历数组。

    代码:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int MinInOrder(int* arr,int left,int right){
        int result=arr[left];
        for(int i=left+1;i<=right;i++){
            if(result>arr[i])
                result=arr[i];
        }
        return result;
    }
    
    int Min(int* numbers,int length){
        if(numbers==NULL || length<=0)
            return -1;
        int left=0;
        int right=length-1;
        int mid=left;
        while(numbers[left]>=numbers[right]){
            if(right-left==1){
                mid=right;
                break;
            }
            mid=left+((right-left)>>1);
            if(numbers[left]==numbers[right] && numbers[left]==numbers[mid])
                return MinInOrder(numbers,left,right);
            if(numbers[mid]>=numbers[left])
                left=mid;
            else
                right=mid;
        }
        return numbers[mid];
    }
    
    int main()
    {
        int A[]={1,0,1,1,1,1,1,1};
        int len=sizeof(A)/sizeof(A[0]);
        Solution s;
        vector<int> nums(A,A+len);
        cout<<s.minNumberInRotateArray(nums)<<endl;
        cout<<Min(A,len)<<endl;
        return 0;
    }

    在线测试OJ:

    http://www.nowcoder.com/books/coding-interviews/9f3231a991af4f55b95579b44b7a01ba?rp=1

    AC代码:

    class Solution {
    public:
    	int minNumberInRotateArray(vector<int> rotateArray) {
    		int len=rotateArray.size();
            if(len==0)
                return 0;
            int left=0;
            int right=len-1;
            int mid=left;
            //if(rotateArray[left]<rotateArray[right]);
            //	return rotateArray[left];
            while(rotateArray[left]>=rotateArray[right]){
                if(right-left==1){
                    mid=right;
                    break;
                }
                mid=left+((right-left)>>1);
                if(rotateArray[left]==rotateArray[right] && rotateArray[left]==rotateArray[mid])
                    return MinInOrder(rotateArray,left,right);
                if(rotateArray[mid]>=rotateArray[left])
                    left=mid;
                else
                    right=mid;
            }
            return rotateArray[mid];
    	}
    
    	int MinInOrder(const vector<int> &arr,int left,int right){
            int result=arr[left];
            for(int i=left+1;i<=right;i++){
                if(result>arr[i])
                    result=arr[i];
            }
            return result;
    	}
    };
    

      

  • 相关阅读:
    vue使用webapck的最基本最简单的开发环境配置
    浏览器里常用的默认事件及事件的属性
    java中的JSON数据转换方法fastjson
    MYSQL mybatis
    js的原型/原型链/构造函数
    面向对象知识点整理(3)
    面向对象知识点整理(2)
    面向对象知识点整理(1)
    DBUtil和连接池 使用
    Math类 BigInteger 类 BigDecimal类 基础用法
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4627647.html
Copyright © 2020-2023  润新知