【劍指Offer】05旋轉陣列的最小數字
阿新 • • 發佈:2018-11-11
題目描述
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{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