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

LeetCode | 二分法题型详解+图解

在做 LeetCode 题时,是否使用二分法可以通过以下几个维度来判断。下面是一些常见信号和典型场景,帮助你判断是否可以或应该使用二分查找:

1.函数或数组在某一方向上是单调的(递增/递减)

2.数据有序 or 可推导出有序逻辑

3.题目中有“最值”或“满足某个条件的最小值/最大值”描述

4.可能的输入规模较大(例如 1e5、1e9)且解空间连续

二分法常用模板

经典(闭区间)二分模板:

left, right = 0, n - 1
while left <= right:mid = (left + right) // 2if check(mid):right = mid - 1  # 或 left = mid + 1,根据目标是找左边界还是右边界else:left = mid + 1

总结:判断是否可以二分的 4 个关键词

特征描述
单调性满足某个条件的区间是连续的(左 False 右 True)
有序性数组本身或逻辑上有序
范围型搜索解的范围是一个区间而不是离散点
最值/边界类问题问最小满足条件值 / 最大不满足条件值

【Leetcode 33】在排序和旋转的数组中搜索 (Search in Rotated Sorted Array)

给定一个升序排列的数组,经过旋转(无重复元素)后变成现在的样子,并给定一个目标值 target,请你在数组中搜索这个目标,如果找到了,返回它的索引;如果没找到,返回 -1

解题思路:二分查找 + 逻辑判断

数组被分成了两个递增区间,我们不能直接用标准二分,而是要结合判断:

  • 每次找中间值 mid

  • 判断哪一边是有序的

  • 再判断 target 落在哪一边

  • 缩小区间继续查找

def search(nums,target):left,right=0,len(nums)-1while left<=right:mid =(left+right)//2if nums[mid]==target:return midif nums[left]<=nums[mid]:if nums[left]<=target<nums[mid]:right=mid-1else:left=mid+1else:if num[mid]<target<=nums[right]:left=mid+1else:right=mid-1return -1

 

【Leetcode 81 】在排序和旋转的数组中搜索Search in Rotated Sorted Array II

允许数组中存在重复元素,你仍然需要判断目标值是否存在,但现在由于重复值存在,无法通过某些条件唯一判断左右哪边有序,所以要更谨慎地处理边界情况

关键思路:二分查找 + 有序区判断

虽然整体数组被打乱了,但它被分成了两个有序的子区间

def search(nums,target):left,right=0,len(nums)-1while left <=right:mid=(left+right)//2if nums[mid]==tagrt:return Trueif nums[left]<nums[mid]if nums[left]<=tagrt <nums[mid]right=mid-1else:left=mid+1if nums[mid]<nums[right]:if nums[mid]< taget <=nums[right]left=mid+1else:right=mid-1#无法判断那边有序else:left+=1right -=1return False #时间复杂度:平均情况:O(log n)#最坏情况:O(n)(当所有元素都相等,比如 [1,1,1,1,1,1,1])

 举例:nums = [4,5,6,7,0,1,2], target = 0

  1. 初始:left=0, right=6

  2. mid=3,nums[3]=7
    → 左边有序(4~7)
    → target=0 不在左边 → 去右边(left=4)

  3. mid=5,nums[5]=1
    → 右边有序(1~2)
    → target=0 不在右边 → 去左边(right=4)

  4. mid=4,nums[4]=0 ✅ 找到!

题号是否允许重复最优时间复杂度最坏时间复杂度特别处理
33❌ 不允许O(log n)O(log n)标准二分
81✅ 允许O(log n)O(n)加了 left++right-- 处理重复值

【Leetcode 153】Find Minimum in Rotated Sorted Array 

给定一个无重复元素升序旋转数组,找到其中的最小值。时间复杂度要求为 O(log n)。

def findMin(nums):left,right=0,len(nums)-1 # 设两个指针 left 和 right,从整个数组范围开始查找#每次取中间位置 mid,然后通过它和 right 比较,来判断最小值在哪一边。while left < right:min=(left+right)//2 # 找中间位置#如果中间的数比右边的大,说明最小值肯定在右边,因为当前 mid 比 right 大,所以最小值不可能是 mid,所以我们把左边界挪到 mid + 1if nums[mid]>nums[right]left=mid+1else:right=mid#当 left == right 的时候,说明找到了最小值的位置,直接返回即可。return nums[left]#时间复杂度:O(log n)(每次折半)#空间复杂度:O(1)(常数变量)

 举例:nums = [4, 5, 6, 7, 0, 1, 2]

  • 第一次:

    • mid = 3 → nums[3] = 7 > nums[6] = 2 → 最小值在右边 → left = 4

  • 第二次:

    • mid = 5 → nums[5] = 1 < nums[6] = 2 → 最小值在左边或 mid → right = 5

  • 第三次:

    • mid = 4 → nums[4] = 0 < nums[5] = 1 → right = 4

此时 left == right == 4,返回 nums[4] = 0

【Leetcode 154】 Find Minimum in Rotated Sorted Array II

给定一个可能包含重复元素升序旋转数组,找到最小值。
要求最优时间复杂度(接近 O(log n),但由于有重复元素,最坏可能退化成 O(n)

def findMin(nums):left, right = 0, len(nums) - 1 #两个指针 left 和 right 来包围可能包含最小值的区域,一开始是整个数组。while left < right:mid = (left + right) // 2 #每次查找中间值的位置。就像在“围住的区间”中切一刀。#三种情况分析:#情况1:中间值比右边的大,说明最小值一定在右边那一段if nums[mid] > nums[right]:left = mid + 1#情况2:中间值比右边小,说明右边那段是递增的,最小值要么在左边,elif nums[mid] < nums[right]:right = mid#情况3(关键!)如果 nums[mid] == nums[right],我们没办法判断最小值在哪边!这是由于重复元素的存在造成的,else:right -= 1  # 不确定在哪边,只能收缩return nums[left]#时间复杂度分析
#平均情况:O(log n)(如果重复值不多)
#最坏情况:O(n)(全部重复或接近重复)

 举例:数组[2, 2, 2, 0, 1]

  • 初始:left=0, right=4

  • mid=2,nums[mid]=2, nums[right]=1
    2 > 1,说明最小值在右边 → left = mid + 1 = 3

  • left=3, right=4

  • mid=3,nums[mid]=0, nums[right]=1
    0 < 1 → 最小值在左边或 mid → right = mid = 3

  • left == right == 3,返回 nums[3] = 0

方法时间复杂度是否处理重复特别策略
I 题O(log n)❌ 无重复标准二分
II 题O(log n) ~ O(n)✅ 支持重复mid == right 时保守 right -= 1

总结:有重复值是三种情况,无重复值就是俩种情况

Leetcode 875. 爱吃香蕉的珂珂
给定吃香蕉的速度 k,能否在 H 小时内吃完? → 单调判断函数 → 二分速度 k

Leetcode 1011. 在 D 天内送达包裹的能力
二分查找最小船运能力(容量)

其他可练习Missing Number,Sum of Two Integers,Number of 1 Bits,Counting Bits,Reverse Bits

我整理了整份资料,刷题卡,想要获得资源,可在VX小程序搜索🔍AI Pulse,发送【leetcode】获取相关资料以及查看AI技术最新内容。

#数据结构 #算法 #二分法 #Leetcode #刷题技巧 

http://www.lryc.cn/news/572348.html

相关文章:

  • bos_token; eos_token; pad_token是什么
  • QSqlDatabase: QSQLITE driver not loaded
  • infinisynapse 使用清华源有问题的暂时解决方法:换回阿里云源并安装配置PPA
  • LoRA 浅析
  • Python Beautiful Soup 4【HTML/XML解析库】 简介
  • StableDiffusion实战-手机壁纸制作 第一篇:从零基础到生成艺术品的第一步!
  • Hexo 个人博客配置记录(GitHub Pages + Butterfly 主题 + Waline 评论 + 自动部署)
  • Kernel K-means:让K-means在非线性空间“大显身手”
  • 职坐标IT培训:嵌入式AI物联网开源项目精选
  • 基于大模型的急性结石性胆囊炎全流程预测与诊疗方案研究
  • 【图像处理入门】11. 深度学习初探:从CNN到GAN的视觉智能之旅
  • 跟着AI学习C# Day22
  • 实时输出subprocess.Popen运行程序的日志
  • 永磁同步电机无速度算法--基于正切函数锁相环的滑模观测器
  • 【鸿蒙HarmonyOS Next App实战开发】​​​​ArkUI纯色图生成器
  • VACM 详解:SNMPv3 的访问控制核心
  • 回溯----8.N皇后
  • C++ std::set的用法
  • 根据图片理解maven
  • FocalAD论文阅读
  • SpringBoot 应用开发核心分层架构与实战详解
  • SpringBoot电脑商城项目--修改默认收货地址
  • 计算机网络:(四)物理层的基本概念,数据通信的基础知识,物理层下面的传输媒体
  • Mac电脑-Office 2024 长期支持版(Excel、Word、PPT)
  • 【数据破茧成蝶】企业数据标准:AI时代的智能罗盘与增长基石
  • 探索大语言模型(LLM):Lora vs. QLora:参数高效微调的双生花,你该选谁?
  • 协作式机器人助力提高生产速度和效益
  • Java泛型详解与阿里FastJSON源码中的巧妙运用
  • 生成式 AI 的发展方向,应当是 Chat 还是 Agent?
  • 华为OD机试-MELON的难题-DFS(JAVA 2025A卷)