leetcode34_Search for a Range

橘子oly發表於2016-11-01

一.問題描述

Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

就是給定一個有序list,找到目標target在list中的第一個和最後一個值的位置,若無則返回[-1,-1],要求時間複雜度為O(logN)。


二.程式碼編寫

    對於有序序列,需求是對數時間複雜度的問題,第一反應就是二分法,對於這種有多個要求輸出的問題,與經典的二分查詢的不同就在於判斷條件多了許多,程式碼編寫的時候要非常細緻,比如在while大迴圈的判斷條件上,邊界是大於等於,而非大於。因為要找到兩端的兩個target的值,所以會有兩個左右指標,在指標移動時也要注意細節。這一題可以用迭代的思想來完成,會使程式碼不顯得這麼冗長,但效率上就不見得優於直接手寫了。程式碼如下:

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        len_nums = len(nums)
        left1=left2 = 0 # 定義兩個指標對(left1,right1)和(left2,right2)
        right1=right2 = len_nums-1
        rlist = [-1,-1]
        while left1<=right1 or left2<=right2:
            if left1==left2 and right1 == right2: # 當兩個指標對相同時
                mid = (left1+right1)/2
                if nums[mid]>target:
                    right1=right2=mid-1
                elif nums[mid]<target:
                    left1=left2=mid+1
                else:
                    if mid>0 and nums[mid-1]==target:
                        right1=mid-1   # 前指標對繼續左移
                    else:
                        rlist[0] = mid
                        left1=-1   # 找到前target後立flag,以免後面程式碼繼續找
                        right1=-2
                    if mid<len_nums-1 and nums[mid+1]==target:
                        left2 = mid+1
                    else:
                        rlist[1]=mid
                        left2=-3  # 找到後target後立flag,以免後面程式碼繼續找
                        right2=-4
            elif left1 != -1:   # 兩個指標對不同且前指標對未找到最左邊的target
                mid1 = (left1+right1)/2
                if nums[mid1]<target:
                    left1=mid1+1
                elif nums[mid1]>target:
                    right1 = mid1-1
                elif mid1>0 and nums[mid1-1]==target:
                    right1 = mid1-1
                else:
                    rlist[0] = mid1
                    left1=-1
                    right1=-2
            elif left2 != -3:  # 兩個指標對不同且後指標對未找到最右邊的target
                mid2 = (left2+right2)/2
                if nums[mid2]<target:
                    left2 = mid2+1
                elif nums[mid2]>target:
                    right2 = mid2-1
                elif mid2<len_nums-1 and nums[mid2+1]==target:
                    left2=mid2+1
                else:
                    rlist[1]=mid2
                    left2=-3
                    right2=-4
        return rlist


執行時間:


相關文章