当前位置: 首页 > news >正文

蓝桥杯算法精讲:二分查找实战与变种解析

适合人群:蓝桥杯备考生 | 算法竞赛入门者 | 二分查找进阶学习者

目录

一、二分查找核心要点

1. 算法思想

2. 适用条件

3. 算法模板

二、蓝桥杯真题实战

例题:分巧克力(蓝桥杯2017省赛)

三、二分查找变种与技巧

1. 查找左边界

2. 查找右边界

四、常见错误与注意事项

五、蓝桥杯进阶练习题


一、二分查找核心要点

1. 算法思想

二分查找(Binary Search)是一种在有序序列中快速定位目标的算法,通过不断缩小搜索范围,将时间复杂度从O(n)降至O(log n)。

2. 适用条件
  • 有序性:数据必须有序(升序或降序)

  • 单调性:问题的解空间具有单调性(如求最大值最小、最小值最大)

3. 算法模板
def binary_search(arr, target):  
    left, right = 0, len(arr) - 1  # 初始化左右指针  
    while left <= right:  
        mid = left + (right - left) // 2  # 防止整数溢出  
        if arr[mid] == target:  
            return mid  # 找到目标,返回索引  
        elif arr[mid] < target:  
            left = mid + 1  # 目标在右半部分  
        else:  
            right = mid - 1  # 目标在左半部分  
    return -1  # 未找到  

二、蓝桥杯真题实战

例题:分巧克力(蓝桥杯2017省赛)

题目描述
有N块巧克力,每块大小为H[i]×W[i]。需切割出K块大小相同的正方形,求最大边长。

问题分析

  • 单调性:边长越大,能切出的块数越少

  • 二分目标:寻找满足块数≥K的最大边长

代码实现

def max_chocolate_size():  
    N, K = map(int, input().split())  
    H = []  
    W = []  
    for _ in range(N):  
        h, w = map(int, input().split())  
        H.append(h)  
        W.append(w)  

    # 二分范围:最小1,最大巧克力边长上限  
    left, right = 1, max(max(H), max(W))  
    ans = 0  
    while left <= right:  
        mid = (left + right) // 2  
        cnt = 0  # 当前边长能切出的总块数  
        for i in range(N):  
            cnt += (H[i] // mid) * (W[i] // mid)  
            if cnt >= K:  # 提前终止循环  
                break  
        if cnt >= K:  
            ans = mid  # 记录可行解  
            left = mid + 1  # 尝试更大的边长  
        else:  
            right = mid - 1  # 边长过大,缩小范围  
    return ans  

print(max_chocolate_size())  

代码解析

  1. 二分初始化:左边界为1,右边界取所有巧克力的最大边长

  2. 计算块数:对每块巧克力计算能切出的块数,累加直至超过K

  3. 调整边界:根据块数是否满足条件,动态调整左右边界

三、二分查找变种与技巧

1. 查找左边界

场景:数组中存在重复元素,找到第一个等于target的位置。

def left_bound(arr, target):  
    left, right = 0, len(arr) - 1  
    while left <= right:  
        mid = left + (right - left) // 2  
        if arr[mid] < target:  
            left = mid + 1  
        else:  
            right = mid - 1  # 压缩右边界  
    # 检查left是否越界或找到目标  
    return left if left < len(arr) and arr[left] == target else -1  
2. 查找右边界

场景:找到最后一个等于target的位置。

def right_bound(arr, target):  
    left, right = 0, len(arr) - 1  
    while left <= right:  
        mid = left + (right - left) // 2  
        if arr[mid] <= target:  
            left = mid + 1  # 压缩左边界  
        else:  
            right = mid - 1  
    # 检查right是否有效  
    return right if right >=0 and arr[right] == target else -1  

四、常见错误与注意事项

  1. 整数溢出:使用mid = left + (right - left) // 2而非(left + right)//2

  2. 边界更新:确保每次循环边界必然缩小,防止死循环

  3. 终止条件while left <= rightleft = mid + 1/right = mid -1配对使用

  4. 返回值验证:最终结果需检查是否有效(如索引是否越界)

五、蓝桥杯进阶练习题

  1. 数的范围(模板题):蓝桥杯题库

  2. 旋转数组的最小值(变种):蓝桥杯2021省赛

  3. 在排序数组中查找元素的第一个和最后一个位置:LeetCode 34

相关文章:

  • CentOS 7扩容 /dev/shm
  • MyBatis-Plus的加载和初始化
  • macOS 使用 iconv 转化文件编码
  • C#里使用libxl来对列或行进行分组显示
  • CTF题目 《FinalSQL》(极客大挑战 2019)WriteUp
  • idea接入 AI 编程助手:Copilot
  • KiLog2MaximumIncrement的由来和KiMaximumIncrementReciprocal的由来
  • 策略模式 vs. 工厂模式:对比与分析
  • 15:视图
  • T113-i开发板的休眠与RTC定时唤醒指南
  • git | 回退版本 并保存当前修改到stash,在进行整合。[git checkout | git stash 等方法 ]
  • 【安全运营】安全运营关于告警降噪的一些梳理
  • NO.55十六届蓝桥杯备战|排序|插入|选择|冒泡|堆|快速|归并(C++)
  • Linux-数据结构-双向链表与栈
  • Linux进程间通信方式
  • TypeScript教程
  • python爬虫可能遇到的小bug
  • 【RK3588嵌入式图形编程】-SDL2-渲染文本
  • CSS 文档流:元素排列的底层逻辑与布局控制
  • stm32-ADC
  • 时代中国控股:前4个月销售额18.1亿元,境外债重组协议押后聆讯至5月底
  • 华泰柏瑞基金总经理韩勇因工作调整卸任,董事长贾波代为履职
  • 市自规局公告收回新校区建设用地,宿迁学院:需变更建设主体
  • 马克思主义理论研究教学名师系列访谈|董雅华:让学生感知马克思主义理论存在于社会生活中
  • 中国以优化营商环境为支点,为全球企业提供可预期市场环境
  • 洲际酒店:今年第一季度全球酒店平均客房收入同比增长3.3%