Leetcode日练4 #34 search for a range

第三种二分法是要求当下算出中值的左右相邻的值。

也就是说每一次都要判别至少3个值。

Leetcode日练4 #34 search for a range_第1张图片

最后是应该剩两个值。

#34 Search for a Range

Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value.

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

You must write an algorithm with O(log n) runtime complexity.

解题思路:

排除edge case,nums里没有元素。

有两大类可能,一类nums里没有target,最后left pointer 和 right pointer会汇合,这种情况直接输出[-1, -1];另一类有target,中值早晚会等于target,这个时候寻找最左端left pointer等于target的,右同。

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        if len(nums) > 0:
            l, r = 0, len(nums)-1
        else:
            return [-1, -1]
        
            
        while r > l:
            m = (l + r)//2
            if nums[m] > target:        # target is on the left
                r = m - 1 
            elif nums[m] < target:      # target is on the right 
                l = m + 1 
            else:                       # nums[m] == target
                while True:             # get l
                    if m > 0:
                        m = m - 1  
                        if nums[m] != target:
                            l = m + 1
                            break
                    else:
                        l = m
                        break
                        
                while True:             # get r
                    if m < len(nums)-1:
                        m = m + 1
                        if nums[m] != target:
                            r = m - 1 
                            break
                    else:
                        r = m
                        break
                break
                
        if nums[l] == target:
            return [l, r] 
        else:
            return [-1, -1]

runtime:

Leetcode日练4 #34 search for a range_第2张图片

 64ms solution sample:

运用了python内置的Bisect Algorithm Functions。给定list和target后,用bisect_left()和bisect_right()找出插入target后依然保持sorted list的index。

import bisect

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        
        
        # if use built-in function
        if nums == None or len(nums) == 0:
            return [-1, -1]
        
        def find(arr, target):
            low, high = 0, len(arr)-1
            
            while low <= high:
                mid = low + (high-low)//2
                if arr[mid] == target:
                    return True
                elif arr[mid] > target:
                    high = mid - 1
                else:
                    low = mid + 1
            
            return False
        
        if not find(nums, target):
            return [-1, -1]
        
        left  = bisect.bisect_left(nums, target)
        right = bisect.bisect_right(nums, target)
        return [left, right-1]

 这种方法相比之下的优点在于,一旦出现中值等于target时,利用bisect的特点寻找左右端的index值。如果一直没出现就输出[-1, -1]。

你可能感兴趣的:(leetcode日练,leetcode,算法,职场和发展)