【二分算法】模板总结

目录

一、二分查找时间复杂度

二、二分查找模板

[2.1 模板一:标准的二分查找](#2.1 模板一:标准的二分查找)

[2.2 模板二:二分查找左边界](#2.2 模板二:二分查找左边界)

[2.3 模板三:二分查找右边界](#2.3 模板三:二分查找右边界)

三、总结:


一、二分查找时间复杂度

时间复杂度可以表示 O(n)=O(log2​n)或者O(n)=O(logn)

二、二分查找模板

什么时候可能需要用二分查找?

(1)待查找的数组有序或者部分有序

(2)可以发现二段性

(3)题目要求时间复杂度低于 O(n),或者直接要求时间复杂度为 O(log n)

2.1 模板一:标准的二分查找

适用场景:数组元素有序且不重复

java 复制代码
public int search(int[] nums, int target) {
        int left = 0,right = nums.length-1;
        while(left<=right) {
            int mid = left + ((right-left)>>1);//+运算的优先级高
            if(target==nums[mid]) return mid;
            else if(nums[mid]<target) left = mid+1;
            else right = mid-1;
        }
        return -1;
    }

注意点:

(1)为什么 while 循环的条件是 <=,而不是 < ?

当元素只有一个且这个元素正好就是目标值,那么没有=就进入不了循环,得不到正确的结果

(2)计算 mid 时需要防止溢出

left + ((right -left) >> 1) 其实和 (left + right) / 2 是等价的,这样写的目的一个是为了防止 (left + right) 出现溢出,另外用位运算替代除法提升性能


2.2 模板二:二分查找左边界

java 复制代码
public int search(int[] nums, int target) {
        int left =0,right = nums.length-1;
        while(left<right) {//1.
            int mid = left+(right-left)/2;//2.
            if(nums[mid]<target) left = mid+1;//3.
            else right = mid;
        }
        if(nums[left]==target) return left;
        return -1;
    }

注意点:

(1)为什么 while 循环的条件是 <,而不是 <= ?

left等于right的时候就已经得到了最终结果,如果判断了,就会进入死循环,因为right后面一直不动

(2) 求中点的操作

求左边界根标准模板一样,不用+1,直接left+(right-left)/2(总个数为偶数个时取中点的时候取左边那个

(3)为啥nums[mid]==target右边界也要变

要寻找左边界,当nums[mid] == target,这个mid的位置不一定就是最左侧的那个边界,所以还要继续收缩右边界

2.3 模板三:二分查找右边界

java 复制代码
public int search(int[] nums, int target) {
        int left =0,right = nums.length-1;
        while(left<right) {//1.
            int mid = left+(right-left+1)/2;//2.
            if(nums[mid]>target) right = mid-1;//3.
            else left=mid;
        }
        if(nums[right]==target) return right;
        return -1;
    }

注意点:

(1)为什么 while 循环的条件是 <,而不是 <= ?

left等于right的时候就已经得到了最终结果,如果判断了,就会进入死循环,因为right后面一直不动

(2) 求中点的操作

这个和求左边界不一样,需要+1,即left+(right-left+1)/2(总个数为偶数个时取中点的时候取右边那个),因为如果最后剩两个元素的时候,left一直找左边那个元素,那么将会进入死循环

(3)为啥nums[mid]==target左边界也要变

要寻找右边界,当nums[mid] == target,这个mid的位置不一定就是最右侧的那个边界,所以还要继续收缩左边界


三、总结:

(1)左+1,右不变

找左边界时,left = mid+1;找右边界,left = mid

(2)下面出现-1的时候,上面就要+1

mid-1出现,那么上面求mid就需要+1

相关推荐
迈巴赫车主6 分钟前
蓝桥杯20560逃离高塔
java·开发语言·数据结构·算法·职场和发展·蓝桥杯
泯仲14 分钟前
Ragent项目7种设计模式深度解析:从源码看设计模式落地实践
java·算法·设计模式·agent
dulu~dulu18 分钟前
算法---寻找和为K的子数组
笔记·python·算法·leetcode
moonsea020328 分钟前
【无标题】
算法
佑白雪乐1 小时前
<ACM进度212题>[2026-3-1,2026-3-26]
算法·leetcode
穿条秋裤到处跑1 小时前
每日一道leetcode(2026.03.26):等和矩阵分割 II
算法·leetcode·矩阵
平凡灵感码头1 小时前
C语言 printf 数据打印格式速查表
c语言·开发语言·算法
哔哔龙1 小时前
Android OpenCV 实战:图片轮廓提取与重叠轮廓合并处理
android·算法
hz_zhangrl1 小时前
CCF-GESP 等级考试 2026年3月认证C++三级真题解析
c++·算法·程序设计·gesp·gesp2026年3月·gesp c++三级
x_xbx1 小时前
LeetCode:1. 两数之和
数据结构·算法·leetcode