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

题目描述

在这里插入图片描述

解题思路

解法一:二分查找法

第一步:通过正常的二分查找法定位到要查找到的元素
第二步:定位到指定的元素后,再找到它的开始和结束位置
举例说明
在这里插入图片描述
当nums[mid] == target时,开始查找第一个和最后一个位置:

  • 查找第一个位置,为了缩小右边界,开始从左边查找,如果nums[mid] = nums[mid-1],则target出现的第一个位置还需继续向左查找,继续使用二分法得到mid=1,小于target,则L加1,继续使用二分法得到mid=2,且nums[mid] != nums[mid-1],则2为target出现的起始位置
  • 查找最后一个位置,同上开始从右边查找,如果nums[mid] = nums[mid+1],则target出现的最后一个位置还需继续向右查找,继续使用二分法得到mid=5,此时nums[mid] != nums[mid+1],则说明5为target出现的终止位置。

python代码

class Solution:
    def searchRange(self, nums, target):
        if not nums:
            return [-1,-1]
        n = len(nums)
# 查找第一个和最后一个元素
        def find(is_find_first):
            begin = 0
            end = n-1
            # if和elif的逻辑跟正常的二分查找一样
            while begin<=end:
                mid = begin+(end-begin)//2
                if nums[mid]>target:
                    end = mid-1
                elif nums[mid]<target:
                    begin = mid+1
                # 找到目标值了,开始定位到第一个和最后一个位置
                else:
                    # 查找第一个和最后一个逻辑很类似,这里用一个变量标记
                    # 是查找第一个还是查找最后一个
                    if is_find_first:
                        # 如果不满足条件,缩小右边界,继续往左边查找
                        if mid>0 and nums[mid]==nums[mid-1]:
                            end = mid-1
                        else:
                            return mid
                    else:
                        # 如果不满足条件,增大左边界,继续往右边查找
                        if mid<n-1 and nums[mid]==nums[mid+1]:
                            begin = mid+1
                        else:
                            return mid
            return -1
        return [find(True), find(False)]
s = Solution()
print(s.searchRange([5,7,8,8,8,8,10],8))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章