美文网首页剑指offer
面试题11. 旋转数组的最小数字

面试题11. 旋转数组的最小数字

作者: 人一己千 | 来源:发表于2020-03-06 13:39 被阅读0次

题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

示例 1:

输入:[3,4,5,1,2]
输出:1

示例 2:

输入:[2,2,2,0,1]
输出:0

注意:本题与主站 154 题相同:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

这一题最简单的解法是n复杂度,过一遍然后记录最小值就好了,但是两段有序数组这个信息没有用到,肯定有更好的解法。
因为是基本有序的,所以二分法可以考虑。
以下代码主要参考leetcode上的一个解法,分析也很好。

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        # 二分法
        i = 0
        j = len(numbers)-1
        while (i<j):
            m = (i+j)//2
            if numbers[m] > numbers[j]:    #
                i = m + 1  # m点已经很大了,所以不可能是最小数字,在右边+1
            elif numbers[m] < numbers[j]:
                j = m        
            else:
                j -= 1    # 同样很关键
        return numbers[i]

总结

个人一开始想的方法是判断某个数两边的数都比它大,写出来的代码考虑很多边界情况,还不如直接记录最小值的办法。
来自leetcode题解,需要注意的点:


image.png

** 要跟右边比较!**
** 后面要 j-=1! **

温故知新

之前并没有完全理解原po的做法,自己动手写了一下,发现return的时候,返回的实际上是 left 而不是mid。
首先,算法的目的是通过缩小i j 之间的范围,最终i=j,找到最小的数字(右排数组的第一位)。
初始化时 i 不一定在左派数组中,j一定在右排数组中 -> 不能让中位数和左边比较。
值相等的时候,j -= 1

相关文章

网友评论

    本文标题:面试题11. 旋转数组的最小数字

    本文链接:https://www.haomeiwen.com/subject/zfavrhtx.html