[LeetCode]34. Search for a Range

34. Search for a Range

因为题目直接就要求时间复杂度为logn,所以很明显是二分查找,注意这个二分查找需要左右两边,不然长度为1的数组无法进入。

我一开始的做法,是通过二分法找到相应的值,在遍历找到最左边和最右边的相同值,但这个有个问题,就是遍历可能会造成O(n)的时间复杂度(比如数组全部的值都是相同的),所以最好找最左边和最右边都需要二分法来找。

之前:

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        l, r = 0, len(nums)-1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                j = i = mid
                while i >= 1 and nums[i] == nums[i-1]:
                    i -= 1
                while j <= len(nums)-2 and nums[j] == nums[j+1]:
                    j += 1
                return [i, j]
            elif nums[mid] < target:
                l = mid + 1
            else:
                r = mid - 1
        return [-1, -1]

之后:

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        if not nums:
            return [-1, -1]
        # 1.left most
        l, r = 0, len(nums)
        while l < r:
            mid = (l + r) // 2
            if nums[mid] < target:
                l = mid + 1
            else:
                r = mid
        l_index = l if 0 <= l < len(nums) and nums[l] == target else -1
        # 2.right most
        r = len(nums)
        while l < r:
            mid = (l + r) // 2
            if nums[mid] > target:
                r = mid
            else:
                l = mid + 1
        r_index = l-1 if 0 <= l-1 < len(nums) and nums[l-1] == target else -1
        return [l_index, r_index]

二分查找有些细节,左边移动情况不加等号,得到的是最左边的值(因为相等情况下全靠右边在移动),相反加等号后,得到的则是最右边的值(因为相等情况下全靠左边在移动)。

posted @ 2017-08-19 09:37  banananana  阅读(157)  评论(0)    收藏  举报