剑指 Offer 53 - I. 在排序数组中查找数字 I

题目描述

方法一:二分查找+遍历

先使用二分查找找到target第一次出现的索引,再从索引处开始遍历

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        index = self.binary_search(nums, target)
        if index == -1:
            return 0
        times = 0
        for i in range(index, len(nums)):
            if nums[i] == target:
                times += 1
            else:
                break
        return times
        

    def binary_search(self, nums: List[int], target: int) -> int:
        """二分查找target在nums中第一次出现的索引"""

        low = 0
        high = len(nums) - 1
        while low <= high:
            middle = int((low + high) / 2)
            if target <= nums[middle]:  # 注意这里是≤,为了找第一次出现的索引
                high = middle - 1
            else:
                low = middle + 1

        if low < len(nums) and nums[low] == target:
            return low
        else:
            return -1

在这里插入图片描述

方法二:用两次二分查找

参考解法

这里要学习查找第一次出现和最后一次出现的索引的不同写法

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left_index = self.binary_search(nums, target, first=True)
        right_index = self.binary_search(nums, target, first=False) - 1     # -1是因为这里的right_index是大于target的第一个索引,-1可以获得target出现的最后一个索引
        if left_index <= right_index and right_index < len(nums) and nums[left_index] == target and nums[right_index] == target:
            return right_index - left_index + 1
        else:
            return 0
        

    def binary_search(self, nums: List[int], target: int, first: bool) -> int:
        """二分查找target在nums中出现的索引
        
        参数
        -----------
            first: bool
                True: 查找target第一次出现的索引
                False: 查找target最后一次出现的索引
        """

        low = 0
        high = len(nums) - 1
        ans = len(nums)
        while low <= high:
            middle = int((low + high) / 2)
            # ≤是为了找第一次出现的索引,<是找最后一次出现的索引
            if (target <= nums[middle] and first) or target < nums[middle]:
                high = middle - 1
                ans = middle    # 这一步是确定返回的索引在数组内部
            else:
                low = middle + 1

        return ans

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值