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

问题描述

https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/

解题思路

我们查找元素的第一个和最后一个元素的位置,题目要求logn,所以只能用二分。

我们用二分求范围时,要注意。这个题目分几种情况。

先看找左边界。我们如果发现mid和target相等,或者是mid大于target,此时我们应该往左侧查找。

如果发现mid <target, 应该往右侧查找。

但是这会出现一个问题。即我们最后left指针可能指向target,也可能指向target左边临近的数。所以我们要做一次额外的判断。

找右边界同理。

代码

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        left = self.handler_left(nums, target)
        right = self.handler_right(nums, target)
        return [left, right]
    def handler_left(self, nums, target):
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] >= target:
                right = mid - 1
            else:
                left = mid + 1
        if 0<=left<len(nums) and nums[left] == target:
            return left
        if 0<=left+1<len(nums) and nums[left+1] == target:
            return left+1
        return -1
    def handler_right(self, nums, target):
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] > target:
                right = mid - 1
            else:
                left = mid + 1
        if 0<=right<len(nums) and nums[right] == target:
            return right
        if 0<=right-1<len(nums) and nums[right-1] == target:
            return right-1
        return -1

 改良一下:

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        left = self.searchLeft(nums, target)
        if left == -1:
            return [-1, -1]
        return [left, self.searchRight(nums, target)]

    def searchLeft(self, nums, target):
        left, right = 0, len(nums)-1
        flag = False
        while left <= right:
            mid = (left+right)>>1
            if nums[mid] == target:
                flag = True
                right = mid - 1
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return left if flag else -1

    def searchRight(self, nums, target):
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)>>1
            if nums[mid] <= target:
                left = mid + 1
            else:
                right = mid - 1
        return right

 

posted @ 2023-01-12 00:03  BJFU-VTH  阅读(23)  评论(0编辑  收藏  举报