LeetCode | 0034. 在排序數組中查找元素的第一個和最後一個位置【Python】

LeetCode 0034. Find First and Last Position of Element in Sorted Array在排序數組中查找元素的第一個和最後一個位置【Medium】【Python】【二分】

Problem

LeetCodepython

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

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

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

Example 1:數組

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:指針

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

問題

力扣code

給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。排序

你的算法時間複雜度必須是 O(log n) 級別。element

若是數組中不存在目標值,返回 [-1, -1]leetcode

示例 1:

輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3,4]

示例 2:

輸入: nums = [5,7,7,8,8,10], target = 6
輸出: [-1,-1]

思路

二分查找

兩次二分查找。
1. 查找 left,因此 nums[mid] < target 時,才移動 left 指針
2. 查找 right,因此 nums[mid] <= target 時,才移動 left 指針
3. lower_bound 返回的是開始的第一個知足條件的位置,而 upper_bound 返回的是第一個不知足條件的位置。因此,當兩個相等的時候表明沒有找到,若是找到了的話,須要返回的是 [left, right - 1]。

時間複雜度: O(logn)
空間複雜度: O(1)

Python代碼

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        # solution one: binary search
        left = self.lowwer_bound(nums, target)
        right = self.higher_bound(nums, target)
        if left == right:
            return [-1, -1]
        return [left, right - 1]
    
    def lowwer_bound(self, nums, target):
        # find in range [left, right)
        left, right = 0, len(nums)
        while left < right:
            mid = int((left + right) / 2)
            if nums[mid] < target:  # <
                left = mid + 1
            else:
                right = mid
        return left
    
    def higher_bound(self, nums, target):
        # find in range [left, right)
        left, right = 0, len(nums)
        while left < right:
            mid = int((left + right) / 2)
            if nums[mid] <= target:  # <=
                left = mid + 1
            else:
                right = mid
        return left

        # # solution two: bisect
        # left = bisect.bisect_left(nums, target)
        # right = bisect.bisect_right(nums, target)
        # if left == right:
        #     return [-1, -1]
        # return [left, right - 1]

代碼地址

GitHub連接

相關文章
相關標籤/搜索