codeforces-go中的二分查找:实现实例

codeforces-go中的二分查找:实现实例

【免费下载链接】codeforces-go 算法竞赛模板库 by 灵茶山艾府 💭💡🎈 【免费下载链接】codeforces-go 项目地址: https://gitcode.com/GitHub_Trending/co/codeforces-go

还在为算法竞赛中的二分查找烦恼吗?一文掌握codeforces-go项目中最实用的二分查找实现技巧!

读完本文,你将收获:

  • ✅ 二分查找的核心原理与使用场景
  • ✅ Go标准库sort.Search的实战技巧
  • ✅ 四种常见二分查找变体的代码实现
  • ✅ 实际竞赛题目的应用案例

📊 二分查找基础概念

二分查找(Binary Search)是一种高效的查找算法,时间复杂度为O(log n)。在算法竞赛中,二分查找常用于:

  • 有序数组查找:快速定位目标元素
  • 二分答案:求解最优解问题
  • 最大化/最小化问题:如最大化最小值、最小化最大值
  • 第K小/大问题:快速定位排序后的第K个元素

二分查找示意图

🔧 Go标准库二分查找用法

codeforces-go项目在copypasta/sort.go中详细展示了Go标准库sort.Search的使用方法:

// 基本二分查找用法
func binarySearch(a []int, target int) int {
    return sort.SearchInts(a, target)  // 返回>=target的第一个下标
}

四种边界情况处理

a := []int{1, 3, 5, 7, 9}
x := 5

lowerBound := sort.SearchInts(a, x)       // >=x的第一个下标
upperBound := sort.SearchInts(a, x+1)     // >x的第一个下标  
lastLE := sort.SearchInts(a, x+1) - 1     // <=x的最后一个下标
lastLT := sort.SearchInts(a, x) - 1       // <x的最后一个下标

🎯 二分查找四大变体实战

1. 二分答案(最大化最小值)

// 最大化最小值:让最小值尽可能大
func maximizeMin(a []int, k int) int {
    return sort.Search(maxValue, func(x int) bool {
        x++  // 关键技巧:判断x+1是否满足
        cnt := 0
        for _, v := range a {
            if v >= x {
                cnt++
            }
        }
        return cnt < k  // 不满足要求返回true
    })
}

2. 二分答案(最小化最大值)

// 最小化最大值:让最大值尽可能小
func minimizeMax(a []int, k int) int {
    return sort.Search(maxValue, func(x int) bool {
        cnt := 0
        for _, v := range a {
            if v <= x {
                cnt++
            }
        }
        return cnt >= k  // 满足要求返回true
    })
}

3. 第K小元素查找

// 在有序矩阵中查找第K小元素
func kthSmallest(matrix [][]int, k int) int {
    n := len(matrix)
    low, high := matrix[0][0], matrix[n-1][n-1]
    
    return low + sort.Search(high-low, func(mid int) bool {
        mid += low
        count := 0
        // 统计<=mid的元素个数
        for i, j := 0, n-1; i < n && j >= 0; {
            if mid < matrix[i][j] {
                j--
            } else {
                count += j + 1
                i++
            }
        }
        return count >= k
    })
}

4. 0-1分数规划

// 求解最大比率问题
func search01(ps [][2]int, k int) float64 {
    // 二分求解∑ai/∑bi的最大值
    l, r := -1.0, 1e5+1
    const eps = 1e-8
    
    for step := 0; step < 100; step++ {
        mid := (l + r) / 2
        arr := make([]float64, len(ps))
        for i, p := range ps {
            arr[i] = float64(p[0]) - mid*float64(p[1])
        }
        sort.Float64s(arr)
        sum := 0.0
        for _, v := range arr[len(arr)-k:] {
            sum += v
        }
        if sum < 0 {
            r = mid
        } else {
            l = mid
        }
    }
    return (l + r) / 2
}

🏆 实际应用案例

案例1:Car Fleet问题

leetcode/weekly/853中有Car Fleet问题的二分查找解法,通过排序+二分快速计算车队数量。

案例2:借教室问题

经典的借教室问题(Luogu P1083)可以通过二分答案+差分数组解决,在copypasta/sort.go中有详细实现思路。

案例3:最大化运行时间

main/1900-1999/中有多题使用二分答案来最大化计算机运行时间,展现了二分查找在优化问题中的强大能力。

💡 使用技巧与注意事项

  1. 边界处理:始终注意数组边界,避免越界访问
  2. 整数溢出:在计算mid时使用int(uint(l+r)>>1)避免溢出
  3. 精度控制:实数二分时,eps通常设为要求精度+2个数量级
  4. 单调性验证:确保二分函数f(x)具有单调性

📚 扩展学习

掌握这些二分查找技巧,你将能轻松解决算法竞赛中60%以上的二分相关问题。多练习、多思考,二分查找将成为你的得力工具!

如果觉得本文对你有帮助,请点赞⭐收藏📁,我们下期再见!

【免费下载链接】codeforces-go 算法竞赛模板库 by 灵茶山艾府 💭💡🎈 【免费下载链接】codeforces-go 项目地址: https://gitcode.com/GitHub_Trending/co/codeforces-go

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值