剑指offer_第6题_旋转数组的最小数字

博客围绕旋转数组最小元素查找展开。先给出题目,即输入非减排序数组的旋转,输出最小元素。接着分析非减排序及数组旋转的意义,指出旋转后数组分两部分,后部分首元素为最小值。最后给出两种解题思路,一是直接找最小元素,二是用二分查找法。

题目描述

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

理解

  • 非减排序想说明什么
    这说明说明旋转前的数组是按照非减的顺序排列的
  • 引入数组的旋转是为了什么
    这说明旋转后的数组分成了两个非减排序的数组,记为array1和array2,array1中的任意元素是大于等于array2中所有数的,所以array2中的第一个数就是我们要找的旋转数组中最小的数。
  • 旋转数组的最小数字

解题思路

思路1
无非是要找出给定数组中的最小元素,不考虑什么数组旋转,直接简单粗暴解决

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        min = rotateArray[0]
        if len(rotateArray) > 0:
            for i in range(1,len(rotateArray)):
                if rotateArray[i] < min:
                    min = rotateArray[i]
            return min
        else:
            return 0

或者

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        else:
            return min(rotateArray)

思路2
利用二分查找法

  • 设置中间点,标记旋转数组首元素和尾元素,中间点将数组分成两半。
  • 如果中间点大于等于首元素,说明最小数字在数组后一半,如果中间点小于等于尾元素,说明最小数字在数组前一半。依次改变首尾元素的位置,当尾元素和首元素挨着的时候,这时候尾元素就是所找的最小值。有一点特殊的是,当首元素等于尾元素等于中间值时,只能对数组进行顺序查找。
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        array_len = len(rotateArray)
        left = 0
        right = array_len - 1
        if array_len==0:
            return 0
        else:           
            while (right - left)> 1:
                mid = (left + right)//2         
                if rotateArray[mid] == rotateArray[left] and rotateArray[mid] == rotateArray[right]:
                    min = rotateArray[left]
                    for i in range(left,right):
                        if rotateArray[i] < min:
                            min = rotateArray[i]
                    return min 
                elif rotateArray[mid]>=rotateArray[left]:
                    left = mid
                elif rotateArray[mid]<=rotateArray[right]:
                    right = mid
        return rotateArray[right]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值