其他分享
首页 > 其他分享> > 牛客剑指offer第六题(旋转数组中的最小数字)

牛客剑指offer第六题(旋转数组中的最小数字)

作者:互联网

题目描述

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

解题思路

该题是典型的二分查找,可分四种情况进行探讨;首先设前半段有序为A段,后半段有序段为B段,由题意可知,A中任一的数都大于B中任意的数,定义三个指针,左指针left ,初始化为0,指向数组的第一个元素,右指针right,初始化为数组长度减1,指向数组的最后一个元素,中间指针mid,始终等于左指针与右指针之和的一半取整。
第一种情况,左指针left在A段,右指针在B段,中间指针mid在数组旋转出的前一个位置,此时通过判断数组的mid位置与mid+1位置的数的大小,即可知这种情况的出现与否,若mid位置的数大于mid+1位置的数,那么数组就是在mid与mid+1中间位置进行了旋转,可知mid+1位置的数即为最小,直接返回该位置的的数即可;
第二种情况,左指针left在A段,右指针在B段,中间指针mid在数组旋转出的后一个位置,此时通过判断数组的mid位置与mid+1位置的数的大小,即可知这种情况的出现与否,若mid位置的数小于mid-1位置的数,那么数组就是在mid-1与mid中间位置进行了旋转,可知mid位置的数为最小,直接返回mid位置的数即可;
第三种情况,左指针left在A段,右指针right在B段,中间指针在A段,但是不在数组旋转出的的前一个位置,此时通过判断mid位置的数与right位置的数的大小,即可知这种 情况的出现与否,若mid位置的数大于right位置的数,即满足该情况,此时将left指针重新指向mid后一位置即可,进入下一个二分查找即可;
第四种情况,左指针left在A段,右指针right在B段,中间指针在B段,但是不在数组旋转出的的后一个位置,此时通过判断mid位置的数与right位置的数的大小,即可知这种 情况的出现与否,若mid位置的数小于right位置的数,即满足该情况,此时将right指针重新指向为mid位置即可,进入下一个二分查找即可;
若在二分查找循环中未捕捉到最小数,退出循环后,直接返回left指针指向的数即可;

代码实现

class Solution:
    def minNumberInRotateArray(self,rotateArray):
        if rotateArray == []:
            return 0
        left = 0
        right = len(rotateArray)-1
        while left < right:
            mid = int((left+right)/2)
            if rotateArray[mid] < rotateArray[mid-1]:
                return rotateArray[mid]
            if rotateArray[mid] > rotateArray[mid+1]:
                return rotateArray[mid+1]
            if rotateArray[mid] > rotateArray[right]:
                left = mid+1
            elif rotateArray[mid] < rotateArray[right]:
                right = mid
            else:
                right -= 1
        return rotateArray[left]


标签:right,offer,位置,mid,牛客,数组,rotateArray,指针
来源: https://blog.csdn.net/LesuperV/article/details/100663458