zoukankan      html  css  js  c++  java
  • 剑指offer:旋转数组的最小数字

    题目描述:

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

    解题思路:

    最直观的想法就是遍历一遍数组,找到最小值,但这样明显没有用到旋转数组这个信息。

    由于这个旋转的操作实际上是将原数组划分成了两个有序的数组,第一个数组是大于第二个数组的,所以考虑用二分的思想。设定两个指针,指针p1指向第一个递增数组,指针p2指向第二个递增数组,两个指针的中间值mid和对应两个指针所指向的值对比,若mid比p1所值元素大,则说明最小元素在后半段,此时p1移动到mid位置,数组长度减半;若mid比p2所值元素小,则说明最小元素在前半段,此时p2移到mid位置。这样到最后,p1和p2就相临,其中p1指向第一个递增数组的最后一位,p2指向第二个递增数组的第一位,即最小值为p2所值元素。

    需要注意以下两个特殊情况:

    1. 若原数组没有旋转,那么第一个元素即为最小值;

    2. 若左右指针所指元素和中间元素都相等,此时就无法决定指针要如何移动,即无法确定最小元素在前半段还是后半段。此时只能通过顺序查找最小元素。

    时间复杂度为O(logn),最坏情况下为O(n)。

    代码:

    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) 
        {
            if(rotateArray.empty())
            {
                return 0;
            }
            int left=0;
            int right=rotateArray.size()-1;
            if(rotateArray[left]<rotateArray[right])
            {
                return rotateArray[left];
            }
            int mid = left;
            while(right>left)
            {
                mid=(right+left)/2;
                int middle=rotateArray[mid];
                int leftNumber=rotateArray[left];
                int rightNumber=rotateArray[right];
                if((right-left)==1)
                {
                    return rightNumber;
                }
                //左中右的值全都相等,不能确定在前还是在后,只能遍历查后一个比前一个小就是最小值
                if(middle==leftNumber&&middle==rightNumber)
                {
                    for(int i=left;i<right;i++)
                    {
                        if(rotateArray[i]>rotateArray[i+1])
                        {
                            return rotateArray[i+1];
                        }
                    }
                //全相等的话直接返回最左值就行了
                    return leftNumber;
                }
                else if(middle<leftNumber)
                {
                    right=mid;
                }
                else if(middle>rightNumber)
                {
                    left=mid;
                }
            }
            return rotateArray[mid];
        }
    };
  • 相关阅读:
    程序界真正的高帅富团体:Valve
    How Unreal Engine 4 Will Change The Next Games You Play【纯搬运】
    互联网“百年老店”是彻头彻尾的扯淡!
    如何关闭VS10中的IntelliSense
    发人深省周鸿祎:少功利多学习 做力所能及的事情
    FlashCS4 快捷键大全
    《1万小时成功定律——解构成功》
    通过AutoExpand调试Unreal内置数据类型
    14 Ways to Motivate Yourself
    关于C++ 动态定义数组
  • 原文地址:https://www.cnblogs.com/LJ-LJ/p/10585435.html
Copyright © 2011-2022 走看看