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