【力扣】1095:山脈數組中查找目標值 |二分查找 |API

題目描述

(這是一個 交互式問題 )
給你一個 山脈數組 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的情況。

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