面試題11 旋轉數組的最小數字(Python3)

把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組 [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

即尋找旋轉數組的最小元素。

 

方法1

直接調用python內置的尋找list中最小值的方法min()

代碼如下;

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        return min(numbers)

萬萬沒想到效果很好:

但這種方法顯然不太合適。

 

方法2 二分法

顯然,這道題的本意是二分法。

即對於索引區間[a,b]及其中點i:

如果numbers[i]<numbers[b], 則最小值在[a,i]之間;

如果numbers[i]>numbers[b], 則最小值在[i,b]之間;

如果numbers[i]==numbers[b],則最小值位置不確定,但一定不是a[b].所以只需要進行b = b-1即可。

直到a==b爲止,返回numbers[a].

 

具體代碼如下:

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        length = len(numbers)
        i = 0
        j = length-1
        m = int((i+j)/2)
        while i<j:
            if numbers[j] > numbers[m]: # 此時最小值在[i,m]之間
                j = m
            elif numbers[j] < numbers[m]: # 此時最小值在[m,j]之間
                i = m+1
            else: # 此時都有可能
                j = j-1
            m = int((i+j)/2)
        return numbers[j]

 

錯誤代碼1

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        length = len(numbers)
        i = 0
        j = length-1
        m = int((i+j)/2)
        while i<j:
            if numbers[j] > numbers[m]: # 此時最小值在[i,m]之間
                j = m
            if numbers[j] < numbers[m]: # 此時最小值在[m,j]之間
                i = m+1
            if numbers[j] == numbers[m]: # 此時都有可能
                j = j-1
            m = int((i+j)/2)
        return numbers[j]

錯誤原因是第一個if如果是True即爲改變j的值(j=m),從而導致改變之後第二個if又是true!這顯然不符合我們的期待,故而出現錯誤。

 

方法2 遍歷方法

顯然,因爲是旋轉數組,因此第一次出現numbers[i]>numbers[i+1]的位置即爲最小值numbers[i].

代碼如下:

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        n = len(numbers)
        for i in range(1,n):
            if numbers[i] < numbers[i-1]:
                return numbers[i]
        return numbers[0]

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章