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

二分法(总体概述)

基础概念

二分法是一种在有序数组(或列表)中查找目标值的算法。它的基本思想是通过逐步缩小查找范围,快速定位目标值。

二分法的步骤
  1. 初始化查找范围:设定左边界left和右边界right
  2. 计算中间位置:找到中间位置mid,通常是mid = left + (right - left) // 2
  3. 比较中间值:将中间位置的值与目标值进行比较:
    • 如果中间值等于目标值,返回其位置。
    • 如果中间值小于目标值,调整左边界到mid + 1
    • 如果中间值大于目标值,调整右边界到mid - 1
  4. 重复步骤2和3,直到找到目标值或查找范围为空(即left > right)。

基本实现

以下是一个基本的二分查找实现:

def binary_search(arr, target):
    """ 二分查找算法
    :param arr: 已排序的数组
    :param target: 要查找的目标值
    :return: 目标值的索引,如果未找到则返回-1
    """
    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  # 未找到目标值

# 测试二分查找算法
arr = [1, 3, 5, 7, 9, 11, 13, 15]
target = 7
result = binary_search(arr, target)
print(f"目标值 {target} 的索引位置为: {result}")

高级例题

  1. 求解平方根:使用二分法求一个非负整数的平方根,允许一定的误差范围。

    def sqrt(x):
        """ 使用二分法求平方根
        :param x: 非负整数
        :return: 平方根值
        """
        if x < 0:
            return -1  # 对于负数,返回-1表示错误
        left, right = 0, x
        precision = 1e-7  # 精度
        while right - left > precision:
            mid = left + (right - left) / 2
            if mid * mid > x:
                right = mid
            else:
                left = mid
        return left
    
    # 测试
    print(sqrt(9))  # 输出接近于3
    
  2. 找出旋转排序数组中的最小值:在一个旋转排序数组中找到最小值。

    def find_min(nums):
        """ 找出旋转排序数组中的最小值
        :param nums: 旋转排序数组
        :return: 最小值
        """
        left, right = 0, len(nums) - 1
        while left < right:
            mid = left + (right - left) // 2
            if nums[mid] > nums[right]:
                left = mid + 1
            else:
                right = mid
        return nums[left]
    
    # 测试
    nums = [4, 5, 6, 7, 0, 1, 2]
    print(find_min(nums))  # 输出0
    
  3. 在排序数组中查找元素的第一个和最后一个位置

    def find_first_last(nums, target):
        """ 查找元素的第一个和最后一个位置
        :param nums: 排序数组
        :param target: 目标值
        :return: 元素的第一个和最后一个位置的索引元组
        """
        def find_position(is_first):
            left, right = 0, len(nums) - 1
            result = -1
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] == target:
                    result = mid
                    if is_first:
                        right = mid - 1  # 查找第一个位置
                    else:
                        left = mid + 1  # 查找最后一个位置
                elif nums[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            return result
    
        first = find_position(True)
        last = find_position(False)
        return (first, last)
    
    # 测试
    nums = [5, 7, 7, 8, 8, 10]
    target = 8
    print(find_first_last(nums, target))  # 输出(3, 4)
    

http://www.kler.cn/a/444487.html

相关文章:

  • VS Code Copilot 与 Cursor 对比
  • Linux设置篇
  • 电源芯片MPQ2179A(TI)
  • Go框架比较:goframe、beego、iris和gin
  • 进程间通信博客总结目录
  • 37. Three.js案例-绘制部分球体
  • Linux下部署MySQL8.0集群 - 主从复制(一主两从)
  • 前后端跨域问题(CROS)
  • shell命令查看在用端口
  • 【图像分类实用脚本】数据可视化以及高数量类别截断
  • Unity 在不同分辨率的屏幕设备中保持特定的纵横比
  • 性能测试度量指标学习笔记
  • Python GUI 编程:tkinter 初学者入门指南——Ttk 组合框 Combobox
  • 课上测试:商用密码接口实现
  • nbcio-vue版本现在安装编译问题的处理方式
  • 工业一体机如何助力汽车零部件制造实现精准控制
  • 数据可视化-1. 折线图
  • Unity开发哪里下载安卓Android-NDK-r21d
  • JAVA集合-LIST 及源码解析
  • 【JAVA】Java项目实战—分布式微服务项目:分布式消息队列
  • Scala项目(一)
  • 3D和AR技术在电商行业的应用有哪些?
  • Flask框架入门与实战
  • meta-llama/Llama-3.2-1B 微调记录
  • 数据库设计范式:全面解析与实践指南
  • 【大模型】GraphRAG技术原理