Python二分模版和bisect函数 LeetCode

23 篇文章 0 订阅
21 篇文章 0 订阅
# 我自己常写的一种 左闭右开
def b1(nums: List[int], target: int) -> int:
    left = 0
    right = len(nums)  # 左闭右开区间 [left, right)
    while left < right:  # 区间不为空
        # 循环不变量:
        # nums[left-1] < target
        # nums[right] >= target
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1  # 范围缩小到 [mid+1, right)
        else:
            right = mid  # 范围缩小到 [left, mid)
    return left  # 或者 right
    
#这种是闭区间写法,注意while循环条件和left和right取值
def b2(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1  # 闭区间 [left, right]
    while left <= right:  # 区间不为空
        # 循环不变量:
        # nums[left-1] < target
        # nums[right+1] >= target
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1  # 范围缩小到 [mid+1, right]
        else:
            right = mid - 1  # 范围缩小到 [left, mid-1]
    return left  # 或者 right+1

# 开区间写法
def b3(nums: List[int], target: int) -> int:
    left, right = -1, len(nums)  # 开区间 (left, right)
    while left + 1 < right:  # 区间不为空
        mid = (left + right) // 2
        # 循环不变量:
        # nums[left] < target
        # nums[right] >= target
        if nums[mid] < target:
            left = mid  # 范围缩小到 (mid, right)
        else:
            right = mid  # 范围缩小到 (left, mid)
    return right  # 或者 left+1

id1=b1(ls, target)
id11=bisect.bisect_left(ls, target)
id2=b2(ls, target)
id22 = bisect.bisect(ls, target)
id3=b3(ls, target)
id33=bisect.bisect_right(ls, target)
我们在不同情况下执行一下上述方法
ls  = [1,3,5,5,5,7,9]
target = 5
print('id1, id11, id2, id22, id3, id33', id1, id11, id2, id22, id3, id33)
结果 id1, id11, id2, id22, id3, id33:  2 2 2 5 2 5

我们假设这里的target是要插入的值。
可以看到,b1()和bisect.left(),b2(), b3()这四个函数,是将target插入到ls满足条件的的最左位置
而bisect.bisect() ,bisect.bisect_right()函数是插入到满足条件的最右位置

如果将target改成4,,此时target不存在于ls中,那么返回的结果是
id1, id11, id2, id22, id3, id33:  2 2 2 2 2 2
这个情况下是一样的

所以总结一下,这里写的b1(), b2(), b3()都是bisect.bisect_left()的具体实现,只是分别用的左闭右开,闭区间和开区间三种不同的思想。

那接下来我们考虑一下怎么实现bisect.bisect_right()函数。
emmm
其实bisect.bisect_right的视线方式可以用

bisect.bisect_left(ls, target+1) 

来实现。
而如果target存在于ls中,我们想找它最后一次出现的位置。
可以用

bisect.bisect_left(ls, target+1) - 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值