題目
有序陣列arr可能經過一次旋轉處理,也可能沒有,且arr可能存在重複的數。例如,有序陣列[1,2,3,4,5,6,7],可以旋轉處理成[4,5,6,7,1,2,3]等。給定乙個可能旋轉過的有序陣列arr,返回arr中的最小值。
基本思路
盡可能的利用二分查詢,但是最壞情況仍然無法避免o(n)的時間複雜度。首先需要知道,如果乙個有序陣列經過旋轉後,最小的值一定是陣列中降序的那個位置,其餘部分都是公升序。同時,陣列的第乙個元素一定比最後乙個元素大。如果沒有經過旋轉,陣列整體都是公升序,最小值就是陣列的第乙個值。
所以在利用二分查詢的時候,如果arr[left] < arr[right],說明陣列整體公升序,直接返回arr[left]。否則,如果arr[left] > arr[mid],說明降序一定發生在陣列左半區,令right = mid;如果arr[mid] > arr[right],說明降序一定發生在陣列右半區,令left = mid。
但是有乙個很重要的問題,在arr陣列中可能存在重複的值,那麼就可能發生arr[left] == arr[mid] == arr[right]的情況。這個時候,我們從left位置開始,向右遍歷,假設遍歷到位置i,如果arr[i] == arr[mid],繼續向右遍歷;如果arr[i] > arr[mid],說明降序一定發生在arr[i…mid]之間,令left = i,right = mid;如果arr[i] < arr[mid],說明此時出現了降序,直接返回arr[i]即可。如果遍歷到mid位置都一直與arr[mid]相等,說明左半區都是乙個值,所以降序一定出現在右半區,所以令left = mid。
最壞的情況下,所有的值都是乙個值。對於每個值都需要遍歷一遍,所以最壞的時間複雜度是o(n)。
def getmin(arr):
low = 0
high = len(arr) - 1
while low < high:
if low == hight - 1:
break
if arr[low] < arr[high]:
return arr[low]
mid = (low + high)//2
if arr[mid] < arr[low]:
high = mid
continue
elif arr[mid] > arr[high]:
low = mid
continue
while low < mid:
if arr[low] == arr[mid]:
low +=1
elif arr[low] < arr[mid]:
return arr[low]
else:
high = mid
break
return min(arr[left],arr[right])
在有序旋轉陣列中找到最小值
在有序旋轉陣列中找到最小值 有序陣列arr可能經過一次旋轉處理,也可能沒有,且arr可能存在重複的數。例如,有序陣列 1,2,3,4,5,6,7 可以旋轉處理成 4,5,6,7,1,2,3 等。給定乙個可能旋轉過的有序陣列arr,返回arr中的最小值。要求 期望複雜度為o log n o log n...
在有序旋轉陣列中查詢最小值
有序陣列a經過一次旋轉處理,也可能沒有旋轉,且a中肯能存在重複的數字。例如有序陣列 1,2,3,4,5,6 可以旋轉處理成 4,5,6,1,2,3 特例一,1,2,3,4,4,4,4,4,4 旋轉成 4,4,4,4,4,1,2,3,4 特例二,1,2,3,4,4,4,4,4,4 旋轉成 4,1,2,...
有序旋轉陣列最小值
題目 有序陣列arr可能經過一次旋轉處理,也可能沒有,且arr可能存在重複的數。例如,有序陣列 1,2,3,4,5,6,7 可以旋轉處理成 4,5,6,7,1,2,3 等。給定乙個可能旋轉過的有序陣列arr,返回arr中的最小值。根據題目分析 有序指公升序 旋轉處理將公升序陣列分成前後兩部分,進行整...