【基础算法精讲 04】二分法……

3 阅读1分钟

题目:34. 在排序数组中查找元素的第一个和最后一个位置

解法:

获取目标值 target 的左端点索引,并将该值赋值给 start ,获取 (target + 1) 的左端点索引 - 1,并将该值赋值给end,[start,end]也即目标 target 在数组(列表)中的索引区间。如果 start 存在,end 就一定存在,返回 [start, end] 。当 start == len(nums) or nums[start] != target ,说明数组中不存在目标值 target ,返回 [-1,-1] 即可

题目中求 ≥ target 的切片区间,当进行需求变更,有如下三种方式: > target 可转化为 ≥ target + 1< target 可转化为 (≥ target) - 1, ≤ target 可转化为 (> target) - 1

时间复杂度:O(log n)

空间复杂度:O(1)

代码实现:

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        start = self.lower_bound(nums, target)
        if start == len(nums) or nums[start] != target:
            return [-1, -1]
        end = self.lower_bound(nums, target + 1) - 1
        return [start, end] # 如果start 存在,end 一定存在
    
    def lower_bound(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1 # 左闭右闭区间
        while left <= right:
            mid = (left + right) // 2 # 向下取整
            if nums[mid] >= target:
                right = mid - 1
            else:
                left = mid + 1
        return right + 1 # left