Bootstrap

python算法-查询区间&经典二分查找问题--Day013

灵活应用二分查找


前言

采用创新方式,精选趣味、实用性强的例子,从不同难度、不同算法、不同类型和不同数据结构进行总结,全面提升算法能力。

例1.查询区间

给定一个包含若干个区间的List数组,长度是1000,如[500,1500],[2100,3100]。给定一个number,判断number是否在这些区间内,返回True或False

示例:输入List=[[100,1100],[1000,2000],[5500,6500]]和number=6000,输出True,因为6000在区间[5500,6500]
输入List=[[100,1100],[2000,3000]]和number=3500,输出False,因为3500不在List的任何一个区间中

代码如下(示例):

class Solut:
    def sol(self,list,num):
        high = len(list) - 1
        low = 0
        while high >= low:#进行二分查找,直到 `high` 小于 `low` 为止
            if 0 < (num - list[(high + low)//2][0]) <= 1000:#计算中间元素的索引 `(high + low) // 2` 并检查中间元素代表的区间是否包含 `num`
                return "True"
            elif 1000 < num - list[(high + low)//2][0]:#查找的区间可以缩小到列表的后半部分
                low = (high + low)//2 + 1
            elif 0 > num - list[(high + low)//2][0]:#查找的区间可以缩小到列表的前半部分。
                high = (high + low)//2 -1
        return "False"
if __name__ == '__main__':
    num = 6000
    list = [[100,1100],[1000,2000],[5500,6500]]
    ss = Solut()
    a = ss.sol(list,num)
    print(a)

得到的结果:True

例2.经典二分查找问题

在一个排序数组中找目标数,返回该目标数出现的任意一个位置,如果不存在,则返回-1

示例,输入nums=[1,2,2,4,5,5],目标数target=2,输出1或2;输入nums=[1,2,2,4,5,5],目标数target=6,输出-1

代码如下(示例):

class Solut:
    def sol(self,nums,target):
        if len(nums) == 0:
            return -1
        start = 0
        end = len(nums) - 1
        while start + 1 < end:#使用一个 `while` 循环来不断缩小搜索范围。在每次循环中,计算中间元素的索引 `mid`,并将其与目标值进行比较
            mid = start + (end - start)//2
            if nums[mid] == target:
                end = mid
            elif nums[mid] < target:
                start = mid
            else:
                end = mid
        if nums[start] == target:
            return start
        if nums[end] == target:
            return end
        return -1
if __name__ == '__main__':
    ss = Solut()
    nums = [1,2,2,4,6]
    x = ss.sol(nums,2)
    print(x)

得到的结果:1


总结

以上是二分查找的案例
二分查找的思路:

  1. 边界检查: 如果数组 nums 为空(长度为0),则直接返回 -1,表示找不到目标值。

  2. 初始化搜索范围: 使用两个指针 startend 来表示数组的搜索范围。开始时,start 指向数组的第一个元素,end 指向最后一个元素。

  3. 二分查找: 使用一个 while 循环来不断缩小搜索范围。在每次循环中,计算中间元素的索引 mid,并将其与目标值进行比较。

    • 如果 nums[mid] 等于 target,则更新 endmid,这意味着目标值可能在左半部分或就是当前位置。
    • 如果 nums[mid] 小于 target,则更新 startmid,因为目标值可能在右半部分。
    • 如果 nums[mid] 大于 target,则不改变 start,但更新 endmid - 1,因为目标值不可能在右半部分(因为数组是有序的)。这样,循环会继续进行直到找到目标值或确定目标值不存在于数组中。
  4. 检查结果: 在循环结束后,检查 nums[start]nums[end] 是否等于目标值。如果等于,则返回相应的索引;否则返回 -1 表示找不到目标值。

;