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

代码随想录 第一章 数组 704.二分查找

代码随想录 第一章 数组 704.二分查找

题目:

  • 题目链接:704. 二分查找
  • 题目描述:给定一个 n​ 个元素有序的(升序)整型数组 nums​ 和一个目标值 target​ ,写一个函数搜索 nums​ 中的 target​,如果目标值存在返回下标,否则返回 -1​。

一、思想

二分查找算法的核心思想是 分治策略,通过 有序数组的有序性 快速缩小搜索范围。具体实现要点:

  1. 有序性前提:数组必须有序(本问题为升序),这是二分查找的根基
  2. 区间收敛:通过不断将搜索区间 对半分割,利用中间值与目标值的比较结果,将搜索范围缩小到左半区或右半区
  3. 终止条件:当搜索区间缩小为空(左指针超过右指针)时确定目标不存在

二、代码

// 左闭右闭的写法
class Solution
{
public:
    /**
     * @brief 二分查找算法实现
     * @param nums 已排序的整型数组(升序排列)
     * @param target 需要查找的目标值
     * @return 目标值在数组中的索引,未找到返回-1
     * @note 二分查找的前提是数组已经是有序的,本函数对有序数组进行二分查找
     */
    int search(vector<int> &nums, int target)
    {
        // 初始化双指针:左边界和右边界
        int left = 0;                // 搜索区间的左端点
        int right = nums.size() - 1; // 搜索区间的右端点

        // 循环终止条件:当左指针超过右指针时说明搜索区间已空
        while (left <= right)
        {
            // 计算中间索引(防止整数溢出的安全写法)
            // 等同于 (left + right)/2,但避免两数相加可能导致的溢出
            int mid = left + (right - left) / 2;

            // 找到目标值的三种情况处理
            if (nums[mid] == target)
            {
                return mid; // 直接返回找到的索引位置
            }
            // 中间值小于目标值时:收缩左边界
            else if (nums[mid] < target)
            {
                left = mid + 1; // +1 排除已检查的mid位置
            }
            // 中间值大于目标值时:收缩右边界
            else
            {
                right = mid - 1; // -1 排除已检查的mid位置
            }
        }

        // 遍历完整个搜索区间未找到目标值
        return -1; // 返回标准未找到标识
    }
};

三、解析

算法工作原理分解

  1. 初始化区间:定义 left=0​, right=size-1​,覆盖整个数组范围

  2. 循环分割

    • 计算中间点 mid = left + (right - left)/2
      (等价于 (left+right)/2​,但避免 left+right​ 整数溢出)
    • nums[mid] == target​:直接命中目标,返回索引
    • nums[mid] < target​:目标在右半区,调整左边界 left = mid + 1
    • nums[mid] > target​:目标在左半区,调整右边界 right = mid - 1
  3. 终止判断:当 left > right​ 时说明区间已空,返回 -1

关键点说明

  1. 循环条件 left <= right
    允许 left == right​ 时进入循环处理单个元素的情况,避免漏判
  2. 边界更新逻辑
    每次排除已检查的 mid​ 位置(+1/-1​),确保搜索区间严格缩小,避免死循环
  3. 整数溢出防御
    mid = left + (right - left)/2​ 写法可避免 left + right​ 超过 INT_MAX​ 的风险

其他写法

区间类型循环条件边界更新规则典型应用场景
左闭右闭left <= rightleft=mid+1right=mid-1标准二分查找
左闭右开left < rightleft=mid+1right=mid动态数组、插入位置
左开右闭left < rightleft=midright=mid-1特殊条件判断

四、复杂度分析

  • 时间复杂度O(log n)
    每次循环将搜索区间减半,最坏情况下需要 log₂n 次比较(n为数组长度)
  • 空间复杂度O(1)
    仅需常数级别的额外空间存储指针变量(left/right/mid)

相关文章:

  • LangChain大模型应用开发:提示词工程应用与实践
  • PHP 面向对象编程
  • win32汇编环境,对话框中使用月历控件示例一
  • vLLM专题(三)-快速开始
  • 二叉搜索树的实现(C++)
  • SSL 连接
  • 网剧《一念逍遥》正式启动筹备
  • 1. 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 。2. 基于 openEuler 构建 LVS-DR 群集。
  • DeepSeek 教我 C++ (3) : Optional / Variant 使用的应该注意的细节
  • Java 中的 HashSet 和 HashMap 有什么区别?
  • [操作系统] 基础IO:系统文件I/O
  • 基于springboot的留学服务管理平台的设计与开发(源码+文档)
  • 【deepseek与chatGPT辩论】辩论题: “人工智能是否应当具备自主决策能力?”
  • BGP分解实验·18——BGP选路原则之权重
  • 网络安全:挑战、技术与未来发展
  • Amazon S3导入Salesforce对象的ETL设计和导入状态日志管理
  • 领域驱动设计(DDD)是什么?——从理论到实践的全方位解析
  • Java gc完整认识和常见问题
  • 【Bluedroid】 BLE连接源码分析(一)
  • 每日OJ_牛客_剪花布条(string内置函数)
  • 商务部就开展加强战略矿产出口全链条管控工作应询答记者问
  • 国台办:台湾自古属于中国,历史经纬清晰,法理事实清楚
  • 横跨万里穿越百年,《受到召唤·敦煌》中张艺兴一人分饰两角
  • 英国收紧移民政策,技术工作签证、大学招生面临更严要求
  • 万科:存续债券均正常付息兑付
  • 十三届全国政协经济委员会副主任张效廉被决定逮捕