33. 搜索旋轉(zhuǎn)排序數(shù)組

image.png

image.png

思路

這題題中說明是升序數(shù)組經(jīng)過了旋轉(zhuǎn)得到,我們可以找到它的旋轉(zhuǎn)點 O(n)
然后根據(jù)旋轉(zhuǎn)點 數(shù)組頭的值 數(shù)組尾的值我們可以確定在哪個區(qū)間使用二分查找 這樣劃出來的區(qū)間都是單調(diào)的 可以二分O(logn)
總的看是O(n)

實現(xiàn)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # 先找分割點
        nums_len = len(nums)
        pivor = 0
        first = nums[0]
        last =nums[0]
        for i in range(nums_len):
            if i-1>-1 and i+1<nums_len and nums[i-1]>nums[i] and nums[i]<nums[i+1]:
                pivor = i
                break
            if i == nums_len-1: # 上面找不到說明是按頭或尾轉(zhuǎn)的
                if first>last: # 逆序
                    pivor = 0
                else:
                    pivor = nums_len-1
        print(pivor)
        # 根據(jù)轉(zhuǎn)點和頭尾判斷在哪個區(qū)間用二分
        left =0
        right =nums_len-1
        if target>=nums[0]:
            left = 0
            right = pivor # 左閉右閉
        else:
            left = pivor
            right =nums_len-1
        while(left<=right):
                mid = left+(right-left)//2
                if nums[mid]<target:
                    left=mid+1
                elif nums[mid]>target:
                    right=mid-1
                elif nums[mid]==target:
                    return mid
        return -1
        

優(yōu)化

二分思想 當(dāng)一個mid確定時 l-mid mid-r必會有一個單調(diào),我們只需要討論清楚target的取值范圍會落到哪個區(qū)間以此二分即可,這樣是O(logn)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # 直接去二分
        nums_len= len(nums)
        l,r = 0,nums_len-1 # 雙閉
        while(l<=r):
            mid = l + (r-l)//2
            if (nums[mid]==target):
                return mid
            if nums[l]<=nums[mid]: # 說明 l-mid 有序
                if target<nums[mid] and target>=nums[l]: # 搜l-mid-1
                    r=mid-1
                elif target>nums[mid] or target<nums[l]: # 搜mid+1-r
                    l=mid+1
            else: # 說明 mid-r 有序
                if target>nums[mid] and target<=nums[r]: # 搜mid+1-r
                    l=mid+1
                elif target<nums[mid] or target>nums[r]: # 搜l-mid-1
                    r=mid-1

        return -1

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容