1. 程式人生 > >【劍指Offer】05旋轉陣列的最小數字

【劍指Offer】05旋轉陣列的最小數字

題目描述

把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。

時間限制:1秒;空間限制:32768K;本題知識點:查詢

解題思路

思路一

首先考慮陣列長度為0和1的情況,然後考慮陣列元素全部相等的情況,除上述情況外從頭到尾遍歷陣列,只要搜尋到後一個元素比前一個小,後一個數即是旋轉陣列的最小元素。這種做法的時間複雜度為O(n)。python程式碼:

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if len(rotateArray) == 0:   #陣列長度為0的情況
            return 0
        elif len(rotateArray) == 1: #陣列長度為1的情況
            return rotateArray[0]
        for i in range(len(rotateArray)-1):
            if rotateArray[i]>rotateArray[i+1]:
                return rotateArray[i+1]
        return rotateArray[0]       #陣列元素全部相等的情況

思路二

再來看這道題目有個特點,旋轉之後的陣列實際上可以劃分成兩個有序的子陣列,而最小的元素就是兩個子陣列的分界線。比較好的思路是用二分查詢,也可能是面試官考核的出發點。這種做法的時間複雜度為O(logn)

思路如下:

(1)用兩個指標left,right分別指向陣列的第一個元素和最後一個元素。

(2)找到陣列的中間元素mid。

(3)比較left元素和mid元素的大小,首先考慮元素無重複的情況。

  • 如果left元素比mid元素小,則說明mid元素在後一個有序的子陣列中,此時最小元素位於mid元素的前面,我們可以讓指標right指向中間元素mid;
  • 如果left元素比mid元素大,則說明mid元素在前一個有序的子陣列中,此時最小元素位於mid元素的後面,我們可以讓指標left指向中間元素mid;
  • 迴圈直到左右指標相鄰,最終left指標將指向前面陣列的最後一個元素,right指標指向後面陣列中的第一個元素,而right指標指向的剛好是最小的元素。

(4)考慮元素重複的情況,若出現left,right,mid元素均相等的情況如 {1,0,1,1,1} 則無法進行二分查詢,改用順序查詢。

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code
        left = 0
        right = len(rotateArray)-1
        if len(rotateArray)==0:
            return 0
        while ((right - left) != 1):
            mid = (left + right) / 2 #整除
            # 中間數和左指標、右指標都相同
            if rotateArray[mid] == rotateArray[left] and rotateArray[right]:
                return min(rotateArray)
            if rotateArray[left] < rotateArray[mid]:
                left = mid
            else:
                right = mid
        mid = right
        return rotateArray[mid]

思路三

最後,分享一個比較bug的做法,能通過但是面試官一定不想給你offer。。。

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code
        if rotateArray:
            return min(rotateArray)
        else:
            return 0