二分查找 二分答案 leetcode 35,34,69,367

参考这个刷题指引
对二分查找的leetcode题目做了几道
以下是学校老师讲的二分查找的模板,我感觉非常的好记
在这里插入图片描述

解释

具体就是需要确定要查找的序列是升序还是降序,以升序为例,查找的位置又可分为四种,是否取等,以及上下界。
关于实现细节,建议left和right采用左闭右开的区间。
四个查找位置又可以转化为两个查找位置,另外两个可以由这两个转换得到,只用记>=target和>target的情况。<target可以由>=target的位置-1得到,<=target可以由>target的位置-1得到。

状态转移时:

当查找>=target的位置时,当f(mid)>=target时,转移r=m,否则转移l=m+1。
当查找>target的位置时,当f(mid)>target时,转移r=m,否则转移l=m+1。
最终返回l的位置即为答案。
mid=l+(r-l)//2时为了防止溢出

35题

在这里插入图片描述

这道题查找的位置是第一个>=target的位置,因此代码如下。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        l = 0
        r = len(nums)
        m = -1
        while l < r:
            m = l + (r-l)//2
            # print(m)
            if nums[m] >= target:
                r = m
            else:
                l = m+1
        
        return l

34题

在这里插入图片描述
这道题需要查找两个位置,一个是>=target的位置,一个是<=target的位置,后者我们采用找>target的位置,然后减1得到。
需要注意,找到的位置的值,可能和target不相等,这时要返回-1。代码如下

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        res1, res2 = -1, -1
        if len(nums) == 0:
            return [res1, res2]
        l , r = 0, len(nums)
        while l<r:
            m = l + (r-l)//2
            if nums[m]>=target:
                r = m
            else:
                l = m + 1
        if l < len(nums) and nums[l] == target:
            res1 = l
        
        l , r = 0, len(nums)
        while l<r:
            m = l + (r-l)//2
            if nums[m]>target:
                r = m
            else:
                l = m + 1
        if l>0 and nums[l-1] == target:
            res2 = l-1
        
        return [res1, res2]

69题

在这里插入图片描述
这道题是一个二分答案的题目,不多想的话,在1~x之间查找m,找到m**2<=target的位置,代码如下。

class Solution:
    def mySqrt(self, x: int) -> int:
        l = 1
        r = x+1
        while l<r:
            m = l +(r-l)//2
            if m**2 > x:
                r = m
            else:
                l = m+1
        return l - 1

367题

在这里插入图片描述
和69题类似,找到后判断m**2和target是否相等,代码如下

class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        l, r = 0, num+1
        while l<r:
            m = l +(r-l)//2
            if m**2 > num:
                r = m
            else:
                l = m+1
        if (l-1)**2 == num:
            return True
        else:
            return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值