題目描述
(這是一個 交互式問題 )
給你一個 山脈數組 mountainArr,請你返回能夠使得 mountainArr.get(index)
等於 target 最小 的下標 index
值。
如果不存在這樣的下標 index
,就請返回 -1。
何爲山脈數組?如果數組 A 是一個山脈數組的話,那它滿足如下條件:
首先,A.length >= 3
其次,在 0 < i < A.length - 1
條件下,存在 i 使得:
A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[A.length - 1]
你將 不能直接訪問該山脈數組,必須通過 MountainArray 接口來獲取數據:
MountainArray.get(k)
- 會返回數組中索引爲k 的元素(下標從 0 開始)
MountainArray.length()
- 會返回該數組的長度
算法思路
值得高興的是我第一時間想到了二分,而且根據題意,需要進行三次二分,第一次找山頂,第二次從升序部分查找,這樣可以得到最小序號,沒有就找降序部分,都沒有返回-1.
但是。
length=mountain_arr.length()
l,r=0,length-1
while l<=r:
mid=(l+r)//2
if mid==0:mid=1;break
if mountain_arr.get(mid-1) <mountain_arr.get(mid)>mountain_arr.get(mid+1):
break
if mountain_arr.get(mid-1) <mountain_arr.get(mid)<mountain_arr.get(mid+1):
l=mid+1
else:
r=mid-1
找山頂的部分,採用這種方式,甚至不得已i打了個補丁:if mid==0:mid=1;break
當mid=0時一定有山頂爲1.
因爲每次比較都調用了三次get方法,所以在最後一個測試例裏失敗了。
class Solution:
def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int:
length=mountain_arr.length()
l,r=0,length-1
while l<=r:
mid=(l+r)//2
if mid==0:mid=1;break
if mountain_arr.get(mid-1) <mountain_arr.get(mid)>mountain_arr.get(mid+1):
break
if mountain_arr.get(mid-1) <mountain_arr.get(mid)<mountain_arr.get(mid+1):
l=mid+1
else:
r=mid-1
kmid=mid
l,r=0,kmid
while l<=r:
mid=(l+r)//2
if mountain_arr.get(mid)==target:return mid
if mountain_arr.get(mid)>target:r=mid-1
else:l=mid+1
l,r=kmid,length-1
while l<=r:
mid=(l+r)//2
if mountain_arr.get(mid)==target:return mid
if mountain_arr.get(mid)>target:l=mid+1
else:r=mid-1
return -1
我選擇去評論區找思路,果然。
一模一樣的思路,只是找山頂這裏有優化。
class Solution:
def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int:
length=mountain_arr.length()
l,r=0,length-1
while l<r:
mid=(l+r+1)//2
# if mid==0:mid=1;break
if mountain_arr.get(mid-1) <mountain_arr.get(mid):
l=mid
else:
r=mid-1
kmid=mid
l,r=0,kmid
while l<=r:
mid=(l+r)//2
if mountain_arr.get(mid)==target:return mid
if mountain_arr.get(mid)>target:r=mid-1
else:l=mid+1
l,r=kmid,length-1
while l<=r:
mid=(l+r)//2
if mountain_arr.get(mid)==target:return mid
if mountain_arr.get(mid)>target:l=mid+1
else:r=mid-1
return -1
執行用時 :40 ms, 在所有 Python3 提交中擊敗了57.69%的用戶
內存消耗 :14.5 MB, 在所有 Python3 提交中擊敗了100.00%的用戶
這裏學到了一個技巧,mid=(l+r+1)//2
來規避mid=0的情況。