二分查找(1)

一.题目

704. 二分查找 - 力扣(LeetCode)

二.思路

提到二分查找 ,很多人第一反应就是"数组必须有序"。其实,这种说法并不准确。二分查找真正的前提是数组具有二分性 。那么,什么是二分性呢?

简单来说,如果你能在数组中找到一个点,将数组划分为三个部分:左区域该点右区域 ,并且能够根据某种规则确定目标位于哪一侧,那么这个数组就具备了二分性 。之所以我们常说"有序才能二分",是因为有序性 是最常见、最简单的规律------它满足左区域 < 中点 < 右区域 ,从而可以轻松判断目标在左边还是右边。可以说,有序只是二分性的一种特例,因为它足够简单,所以流传最广。

三.代码演示

cpp 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) 
    {
        int left = 0;
        int right = nums.size()-1;
        while(left <= right)
        {
            //left+(right - left)/2防止溢出
            int mid = left + (right - left)/2;//求中间点
            if(nums[mid] == target)
                return mid;
            else if(nums[mid] < target)
                left = mid+1;
            else
                right = mid - 1;
        }    
        return -1;
    }
};

四.代码讲解

第一步:问题理解与前提

  • 本题给定一个升序排列 的整数数组 nums 和一个目标值 target,要求返回 target 在数组中的索引,如果不存在则返回 -1。

  • 由于数组有序,具备二分性 ,我们可以利用二分查找算法高效求解。


第二步:初始化左右指针

  • 定义左指针 left = 0,指向数组第一个元素。

  • 定义右指针 right = nums.size() - 1,指向数组最后一个元素。

  • 这两个指针用于维护当前搜索的区间,初始为整个数组。


第三步:循环查找

  • 使用 while 循环,条件为 left <= right
    为什么是 <= 而不是 <

    因为当 left == right 时,区间内还有一个元素需要检查,如果此时退出循环就会漏掉该元素。使用 <= 可以确保区间内所有元素都被覆盖。


第四步:计算中间位置(防溢出)

  • 中间位置 mid = left + (right - left) / 2
    为什么不直接用 (left + right) / 2

    leftright 都很大时,left + right 可能超过 int 范围导致溢出。使用 left + (right - left)/2 可以避免此问题,是安全的写法。


第五步:比较中间值与目标

  • 如果 nums[mid] == target,说明找到目标,直接返回 mid

  • 如果 nums[mid] < target,说明目标在右半区间 ,因为数组有序,所有比 mid 小的元素都在左边,而目标更大,所以更新 left = mid + 1,舍弃左半部分。

  • 如果 nums[mid] > target,说明目标在左半区间 ,更新 right = mid - 1,舍弃右半部分。


第六步:循环结束

  • 如果循环结束仍未返回,说明 target 不在数组中,返回 -1

重点总结

  • 二分查找的核心:每次将搜索区间缩小一半,时间复杂度 O(log n)。

  • 循环条件 :必须用 left <= right,确保最后一个元素被检查。

  • 中间值计算 :使用 left + (right - left)/2 避免溢出。

  • 指针更新 :根据比较结果,将 leftright 移动到 mid 的相邻位置,因为 mid 已经检查过,无需再包含。

这个基础二分查找是所有变体(如寻找左右边界、旋转数组等)的基石,理解每一步的逻辑至关重要

相关推荐
困死,根本不会1 小时前
【C 语言】指针学习笔记:从底层原理到实战应用
c语言·开发语言·笔记·学习·算法
小范自学编程2 小时前
算法训练营 Day38 - 动态规划part07
算法·动态规划
星空露珠2 小时前
迷你世界UGC3.0脚本Wiki全局函数
开发语言·数据库·算法·游戏·lua
小王不爱笑1322 小时前
排序算法 Java
数据结构·算法·排序算法
无敌憨憨大王2 小时前
二叉树的最短路径长度(BFS+DFS)
算法·深度优先·宽度优先
tankeven2 小时前
HJ132 小红走网格
c++·算法
小璐资源网3 小时前
算法黑箱的可解释性危机
算法
不想看见4043 小时前
Power of Four二进制特性--力扣101算法题解笔记
数据结构·算法
做怪小疯子3 小时前
Leetcode刷题——8.重叠区间
算法·leetcode·职场和发展