【剑指offer】07-旋转数组中的最小数字

题目:

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

输入一个【非递减排序的】数组的一个旋转,输出旋转数组的最小元素。

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

NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。


思路:

二分查找法, 详情见书P83【后续自己整理思路】

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        """利用二分查找"""
        n = len(rotateArray)
        first = 0
        last = n-1
        # 先要考虑题目中的特殊情况
        if not rotateArray:
            return 0
        if n == 1:
            return rotateArray[first]
        while first <= last:
            mid = (first + last) // 2
            # 先看找到最小值 是什么个情况
            if rotateArray[mid] < rotateArray[mid-1]:
                # 如果mid刚好比前面那个值小,说明mid就是最小值,∵是非递减数列
                return rotateArray[mid]
            elif rotateArray[mid] < rotateArray[last]:
                # 如果mid比最后小,说明最小值在mid的左边,last游标就移动到现在mid的前面一个
                last = mid - 1
            else:
                first = mid + 1
        return 0


if __name__ == '__main__':
    S = Solution()
    # 用例1:正常数组
    print(S.minNumberInRotateArray([3, 4, 5, 1, 2]))
    # 用例2:正常数组,有重复数字
    print(S.minNumberInRotateArray([4, 4, 5, 1, 2, 3]))
    # 用例3:边界值:升序数组
    print(S.minNumberInRotateArray([3, 4, 5, 6, 7, 9]))
    # 用例4:边界值:只有一个数字的数组
    print(S.minNumberInRotateArray([9]))
    # 用例5:特殊:空数组
    print(S.minNumberInRotateArray([]))

引申题目(小米2019测开笔试题):

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

输入一个【排好序的】数组的一个旋转,输出旋转数组的最小元素。

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


 其他人的代码:【后续自己整理思路】

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        """利用二分查找"""
        n = len(rotateArray)
        first = 0
        last = n-1
        # 先要考虑题目中的特殊情况
        if not rotateArray:
            return 0
        if n == 1:
            return rotateArray[first]
        while first <= last:  # # 只要范围没有缩小到只包含一个元素,就检查中间的元素
            mid = (first + last) // 2  # 如果(low + high)不是偶数,Python自动将mid向下取整
            if rotateArray[mid] > rotateArray[last]:  # 当中间元素大于最后一个,表明最小值在右半区间
                first = mid + 1
            elif rotateArray[mid] < rotateArray[last]:  # 当中间元素小于最后一个,表明最小值在左半区间,注意没有减一操作
                last = mid
            else:
                last -= 1  # 当中间元素等于最后一个,说明没有指定的元素,将范围缩小一
        return rotateArray[mid]


if __name__ == '__main__':
    """我卡 笔试题里要有输入输出啊!"""
    listx = input()
    listy = []
    for ix in listx.split(' '):
        listy.append(int(ix))  # 输入的数放到数组里面
    S = Solution()
    minValue = S.minNumberInRotateArray(listy)
    print(minValue)  # 最终结果要打印出来

笔试题里,要写输入输出!

原文地址:https://www.cnblogs.com/RebeccaG/p/11953937.html