二分查找及常见变体

简介: 二分查找及常见变体

概述


二分查找作为经典的查找算法,思想比较简单,日常使用频繁。每次编写二分相关代码,经常会出现左右区间混乱,不知道如何划分区间等问题,造成做不出题目。


代码分析


  • 区间的左右开闭问题: [0, length - 1]
  • 循环边界: while left < right,这样可以保证最终返回值left == right,随便返回哪个都可以
  • 区间[left.. right]可以划分为两种情况:
  • 分为[left..mid][mid+1..right],分别对应right = midleft = mid + 1
  • 分为[left..mid-1][mid..right],分别对应right = mid-1left = mid。在这种情况下,需要将mid = left + (right - left) / 2修改为 mid = left + (right - left + 1) / 2,否则将出现死循环。


例如 nums = [1,2,3,5]target = 5,若不修改 mid 计算,便会出现死循环


常见二分变体


查找第一个等于给定值的元素


第一个等于,逻辑上发生在数组左边,因此收缩右边界。


def firstEquals(nums, target):
    left, right = 0, len(nums) - 1 
    while left < right: 
        mid = left + (right - left)//2 # 防止溢出, //表示整除
        if nums[mid] < target: 
            left = mid + 1 
        else:
            right = mid # 收缩右边界
    return left 
复制代码


查找最后一个等于给定值的元素


最后一个等于,逻辑上发生在数组右边,因此收缩左边界。


def lastEquals(nums, target): 
    left, right = 0, len(nums) - 1
    mid = left + (right - left + 1) // 2
    while left < right:
        if nums[mid] > target:
            right = mid - 1
        else :
            left = mid
    return left
复制代码


查找第一个大于等于给定值的元素


第一个大于等于,逻辑上发生在数组左边,因此收缩右边界。


def firstLessEquals(nums, target): 
    left, right = 0, len(nums) - 1
    mid = left + (right - left) // 2
    while left < right:
        if nums[mid] < target:
            left = mid + 1
        else :
            right = mid
    return left
复制代码


查找最后一个小于等于给定值的元素


最后一个小于等于,逻辑上发生在数组右边,因此收缩左边界。


def firstLessEquals(nums, target): 
    left, right = 0, len(nums) - 1
    mid = left + (right - left + 1) // 2
    while left < right:
        if nums[mid] > target:
            right = mid - 1
        else :
            left = mid
    return left
复制代码


总结



通过多个角度的学习,自己暂且总结一个自用结论,当查找或者插入为第一个(偏左侧)时,收缩右边界right = mid;当为最后一个(偏右侧)时,收缩左边界left = mid


往期精彩文章



后语


如果大家感觉此文对你有一些帮助,希望能点个赞,鼓励鼓励阿包,阿包会不断努力的。另外如果本文章有问题,或者对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!


相关文章
|
存储 Prometheus Cloud Native
Thanos 工作原理及组件简介
Thanos 工作原理及组件简介
|
存储 算法 关系型数据库
【CEPH-初识篇】ceph详细介绍、搭建集群及使用,带你认识新大陆
你好,我是无名小歌。 今天给大家分享一个分布式存储系统ceph。 什么是ceph? Ceph在一个统一的系统中独特地提供对象、块和文件存储。Ceph 高度可靠、易于管理且免费。Ceph 的强大功能可以改变您公司的 IT 基础架构和管理大量数据的能力。Ceph 提供了非凡的可扩展性——数以千计的客户端访问 PB 到 EB 的数据。ceph存储集群相互通信以动态复制和重新分配数据。
1655 0
【CEPH-初识篇】ceph详细介绍、搭建集群及使用,带你认识新大陆
|
SQL 分布式计算 MaxCompute
MaxCompute SQL使用小技巧之多列转多行
上一篇分析了常用的行列转换,在这里补充一点使用posexplode函数进行多列转多行
1125 0
|
XML Java 数据格式
Spring注解开发管理第三方bean及依赖注入
Spring注解开发管理第三方bean及依赖注入
275 0
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
Linux
深入理解Linux虚拟内存管理(七)(上)
深入理解Linux虚拟内存管理(七)
322 1
|
移动开发 安全 JavaScript
MAX4/11/03/016/08/1/1/00 MAX-4/11/01/008/08/1/1/00
MAX4/11/03/016/08/1/1/00 MAX-4/11/01/008/08/1/1/00
134 0
|
Go API 微服务
Golang微服务框架Kratos轻松集成并使用Swagger UI
在我们的开发当中,调试接口,测试接口,提供接口文档给前端,那都是非常频繁的工作内容。 那么,我们需要用什么方法和工具来实施这些工作内容呢? Swagger,或者说OpenAPI。
659 0

热门文章

最新文章