二分查找算法

Posted 战场小包

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找算法相关的知识,希望对你有一定的参考价值。

二分查找

概述

二分查找作为经典的查找算法,思想比较简单,但每次写相关代码,总出现左右区间混乱,最终造成死循环。

代码分析

  • 区间的左右开闭问题: [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

以上是关于二分查找算法的主要内容,如果未能解决你的问题,请参考以下文章

python算法:二分查找

java 二分查找法

二分查找算法讲解及其C++代码实现

leetcode查找算法(顺序查找,二分法,斐波那契查找,插值查找,分块查找)

二分查找算法

python算法之二分查找