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

从‘折半查找’到‘二分答案’:LeetCode实战中如何活用这个O(log n)的经典思想

从二分查找到二分答案LeetCode实战中的O(log n)思想进阶指南在算法学习与面试准备过程中二分查找Binary Search往往是第一个让初学者感受到算法效率之美的经典案例。这个看似简单的折半查找思想却能在有序数据集合中以O(log n)的时间复杂度完成搜索任务效率远超线性查找。然而许多学习者在掌握了基础版本后面对LeetCode上各种变形题目时仍会感到困惑——为什么这个看似只适用于有序数组的算法却能解决峰值查找、旋转数组搜索甚至最优化问题1. 二分查找的本质再思考二分查找之所以高效核心在于它每次操作都将问题规模减半。这种分而治之的策略不仅适用于静态有序数组的精确查找更是一种普适的问题解决框架。理解这一点是将其思想迁移到更复杂场景的关键。1.1 经典二分查找的三要素任何二分查找的实现都离不开三个核心要素有序性数据必须具有某种单调性不一定是严格递增/递减边界移动根据中间值的比较结果调整搜索范围终止条件明确何时停止搜索通常是左右边界交叉以最基本的查找目标值为例def binary_search(nums, target): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 # 避免溢出 if nums[mid] target: return mid elif nums[mid] target: left mid 1 else: right mid - 1 return -1这个模板看似简单但其中每个决策点都可能在不同场景下发生变化。比如在某些问题中left mid 1可能需要变为left mid而终止条件也可能变为left right。1.2 从查找值到查找边界LeetCode第34题在排序数组中查找元素的第一个和最后一个位置是二分查找的第一个重要变体。它要求我们不仅找到目标值还要找到其出现的左右边界。这需要我们对标准二分查找进行两处关键修改查找左边界时当nums[mid] target不立即返回而是继续向左搜索查找右边界时同理相等时继续向右搜索def search_range(nums, target): def find_left(): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 if nums[mid] target: right mid - 1 else: left mid 1 return left if left len(nums) and nums[left] target else -1 def find_right(): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 if nums[mid] target: left mid 1 else: right mid - 1 return right if right 0 and nums[right] target else -1 return [find_left(), find_right()]这种修改体现了二分思想的灵活性——我们可以通过调整比较逻辑和边界移动策略来解决更复杂的问题。2. 二分思想的进阶应用非精确匹配问题当问题从查找特定值变为查找满足某种条件的极值时二分思想展现出更强大的威力。这类问题通常被称为二分答案问题。2.1 峰值查找问题LeetCode第162题寻找峰值是一个典型例子。题目要求在无序数组中找到任意一个峰值大于相邻元素的值且时间复杂度应为O(log n)。这看起来与二分查找的前提有序性相矛盾实则不然。关键在于发现隐藏的单调性如果nums[mid] nums[mid1]说明右侧存在峰值否则左侧存在峰值def find_peak_element(nums): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 if nums[mid] nums[mid 1]: left mid 1 else: right mid return left这个实现有几个值得注意的特点循环条件变为left right而非left right边界移动时right mid而非right mid - 1不需要检查nums[mid] nums[mid1]的情况题目保证相邻元素不相等2.2 旋转数组中的搜索LeetCode第33题搜索旋转排序数组将难度进一步提升。数组在某个点旋转后整体不再有序但局部仍然保持有序性原数组: [0,1,2,4,5,6,7] 旋转后: [4,5,6,7,0,1,2]解决这类问题的关键在于先确定哪一半是有序的检查目标值是否在该有序半区内根据结果决定搜索方向def search_rotated(nums, target): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 if nums[mid] target: return mid # 左半区有序 if nums[left] nums[mid]: if nums[left] target nums[mid]: right mid - 1 else: left mid 1 # 右半区有序 else: if nums[mid] target nums[right]: left mid 1 else: right mid - 1 return -1这个解法展示了二分思想的另一个重要方面条件判断的灵活性。我们不再简单地比较中间值与目标值而是先判断哪部分有序再决定搜索方向。3. 二分答案解决最优化问题二分思想最强大的应用之一是将最优化问题转化为判定问题。这类问题的共同特点是存在一个最优解的目标值对于任意给定的值可以判断它是否可行可行解具有单调性如果x可行则所有小于/大于x的值也可行3.1 经典案例木头切割问题假设我们有一堆木头需要切割出至少k段等长的木块求每段的最大可能长度。这是一个典型的二分答案问题目标最大切割长度在1到最大原木长度之间判定给定长度x能否切割出至少k段单调性如果x可行则所有小于x的长度也可行def max_wood_length(woods, k): left, right 1, max(woods) answer 0 while left right: mid left (right - left) // 2 total sum(wood // mid for wood in woods) if total k: answer mid left mid 1 else: right mid - 1 return answer3.2 LeetCode实战最小化最大值LeetCode第410题分割数组的最大值要求将数组分成m个连续子数组使这些子数组和的最大值最小。这同样可以使用二分答案解决目标最小的最大子数组和在数组最大值和总和之间判定给定一个最大值限制能否将数组分成不超过m个子数组单调性如果x可行则所有大于x的值也可行def split_array(nums, m): def is_possible(limit): count 1 current 0 for num in nums: current num if current limit: count 1 current num if count m: return False return True left, right max(nums), sum(nums) answer right while left right: mid left (right - left) // 2 if is_possible(mid): answer mid right mid - 1 else: left mid 1 return answer这种模式几乎可以套用于所有最小化最大值或最大化最小值类问题关键在于设计高效的判定函数。4. 二分实现的陷阱与技巧即使理解了二分思想实际编码时仍会遇到各种边界问题。以下是几个常见陷阱及应对策略4.1 避免无限循环二分查找最令人头疼的问题之一是循环无法终止。这通常由边界更新不当引起当使用left mid时必须确保mid计算是left (right - left 1) // 2向上取整当使用right mid时mid应保持left (right - left) // 2向下取整提示在二分实现中先确定循环条件left right或left right再统一边界更新方式可以避免许多边界错误。4.2 处理重复元素当数组包含大量重复元素时标准二分查找可能退化为O(n)时间复杂度。例如在[1,1,1,...,1]中查找第一个或最后一个1的位置。这时需要查找左边界相等时移动右指针查找右边界相等时移动左指针4.3 浮点数二分当处理浮点数范围时如求平方根二分同样适用但需要注意循环条件改为判断精度while right - left 1e-6不需要处理整数除法的取整问题边界更新直接赋值left mid或right middef sqrt(x): if x 0: raise ValueError left, right 0, x while right - left 1e-6: mid (left right) / 2 if mid * mid x: left mid else: right mid return left在实际面试中我遇到过不少候选人能够写出标准二分查找但面对变种问题时却束手无策。究其原因往往是对二分思想的本质理解不够深入——它不仅仅是一种查找算法更是一种通过条件判断不断缩小问题规模的通用策略。

相关文章:

从‘折半查找’到‘二分答案’:LeetCode实战中如何活用这个O(log n)的经典思想

从二分查找到二分答案:LeetCode实战中的O(log n)思想进阶指南 在算法学习与面试准备过程中,二分查找(Binary Search)往往是第一个让初学者感受到算法效率之美的经典案例。这个看似简单的"折半查找"思想,却能…...

Reachy Mini桌面机器人:开源AI机器人开发的终极指南

Reachy Mini桌面机器人:开源AI机器人开发的终极指南 【免费下载链接】reachy_mini Reachy Minis SDK 项目地址: https://gitcode.com/GitHub_Trending/re/reachy_mini Reachy Mini是一款专为开发者和AI研究者设计的开源桌面机器人,通过其精密的六…...

SiameseAOE中文-base多场景落地:金融投诉文本中‘服务态度’‘处理时效’双抽取

SiameseAOE中文-base多场景落地:金融投诉文本中‘服务态度’‘处理时效’双抽取 1. 模型简介 SiameseAOE通用属性观点抽取-中文-base是一个专门用于中文文本信息抽取的AI模型。它基于先进的提示(Prompt)文本(Text)构…...

OpenClaw+Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF:3个低成本自动化场景实测

OpenClawQwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF:3个低成本自动化场景实测 1. 为什么选择这个组合? 上个月在折腾个人自动化工作流时,我遇到了一个典型矛盾:既希望AI能处理复杂的代码和文档任务,又受限…...

多模态交互概念展示:LFM2.5-1.2B-Thinking-GGUF如何理解并处理图像描述文本

多模态交互概念展示:LFM2.5-1.2B-Thinking-GGUF如何理解并处理图像描述文本 1. 当文本模型遇见视觉世界 你可能好奇,一个纯文本模型如何参与多模态交互?关键在于语义桥梁的搭建。LFM2.5-1.2B-Thinking-GGUF虽然不能直接处理图像&#xff0c…...

Waymo Open Dataset Docker部署:环境配置与容器化最佳实践

Waymo Open Dataset Docker部署:环境配置与容器化最佳实践 【免费下载链接】waymo-open-dataset Waymo Open Dataset 项目地址: https://gitcode.com/gh_mirrors/wa/waymo-open-dataset Waymo Open Dataset是自动驾驶领域的重要开源项目,提供了丰…...

AI编程专栏(三) - Cursor 高级技巧与实战优化

1. Cursor高级功能深度解析 第一次接触Cursor时,你可能觉得它就是个带AI的代码编辑器。但当我真正用它完成一个企业级项目后,才发现那些藏在深处的功能才是真正的生产力神器。比如最近在重构一个老旧的React项目时,通过合理使用MCP协议&#…...

Pixel Mind Decoder 效果惊艳展示:多语言文本情绪解码对比

Pixel Mind Decoder 效果惊艳展示:多语言文本情绪解码对比 1. 情绪解码技术的新突破 在数字沟通日益频繁的今天,准确理解文字背后的情绪成为AI领域的重要挑战。Pixel Mind Decoder作为新一代多语言情绪分析工具,通过深度学习模型实现了对文…...

老旧Windows 7系统硬件适配难题的技术解决方案:开源社区驱动的扩展支持包

老旧Windows 7系统硬件适配难题的技术解决方案:开源社区驱动的扩展支持包 【免费下载链接】win7-sp2 UNOFFICIAL Windows 7 Service Pack 2, to improve basic Windows 7 usability on modern systems and fully update Windows 7. 项目地址: https://gitcode.com…...

Java线程池中如何用TransmittableThreadLocal避免变量丢失?附完整Demo

Java线程池中TransmittableThreadLocal的实战应用与避坑指南 在Java高并发编程中,线程池是提升性能的利器,但线程复用机制却给上下文传递带来了挑战。当我们在父线程设置变量,子线程却无法获取时,这种"断链"现象常让开发…...

Anything to RealCharacters 2.5D转真人引擎:AI艺术展数字作品写实化呈现

Anything to RealCharacters 2.5D转真人引擎:AI艺术展数字作品写实化呈现 你是否曾想过,将那些精美的二次元插画、可爱的卡通头像,或者充满想象力的2.5D游戏角色,一键变成栩栩如生的真人照片?这听起来像是电影里的特效…...

CLIP-GmP-ViT-L-14模型部署保姆级教程:从零开始的Docker环境配置

CLIP-GmP-ViT-L-14模型部署保姆级教程:从零开始的Docker环境配置 你是不是也对那些能看懂图片的AI模型感到好奇?比如,你上传一张猫的照片,AI不仅能认出是猫,还能告诉你这是橘猫,正在晒太阳。CLIP-GmP-ViT-…...

nlp_structbert_sentence-similarity_chinese-large赋能智能客服:精准匹配用户问题与知识库

nlp_structbert_sentence-similarity_chinese-large赋能智能客服:精准匹配用户问题与知识库 你有没有遇到过这样的情况?在某个App里找客服,输入了一大段问题,结果机器人回复的答案要么是“牛头不对马嘴”,要么就是让你…...

保姆级教程:在RTX 5090上跑通CosyVoice2语音合成,并集成vLLM加速

在RTX 5090上部署CosyVoice2语音合成:从环境配置到vLLM加速实战 当你刚拿到Nvidia RTX 5090显卡时,最兴奋的莫过于用它来跑最新的AI模型。CosyVoice2作为当前最先进的语音合成框架之一,结合vLLM的推理加速能力,能在RTX 5090上实现…...

lite-avatar形象库使用手册:浏览、选择、集成三步搞定

lite-avatar形象库使用手册:浏览、选择、集成三步搞定 在数字人应用开发中,选择合适的虚拟形象往往是项目启动的第一个挑战。传统方式需要从零开始建模、训练,不仅耗时耗力,结果也难以保证。lite-avatar形象库的出现,…...

生成式 AI 赋能下钓鱼攻击的技术异化与防御体系构建

摘要 生成式人工智能在文本创作、语义理解与内容生成领域的快速落地,在提升生产效率的同时,也被不法分子用于网络钓鱼攻击的智能化升级。路透社与哈佛大学联合测试显示,主流大语言模型在特定提示词绕过机制下可生成高仿真钓鱼邮件&#xff0c…...

为什么你的FastAPI AI接口在K8s里流式失败?——基于eBPF追踪的12层网络栈+ASGI生命周期时序图(含cgroup内存隔离失效证据)

第一章:FastAPI 2.0 异步 AI 流式响应对比评测报告FastAPI 2.0 原生强化了对 async/await 的深度支持,尤其在处理大语言模型(LLM)的逐 token 流式生成场景中,显著提升了吞吐量与首字节延迟(TTFB&#xff09…...

nlp_structbert_sentence-similarity_chinese-large一键部署教程:Python环境快速配置指南

nlp_structbert_sentence-similarity_chinese-large一键部署教程:Python环境快速配置指南 想快速上手一个强大的中文文本相似度计算模型吗?今天咱们就来聊聊怎么在星图GPU平台上,用最简单的方式把 nlp_structbert_sentence-similarity_chine…...

Java 25虚拟线程资源隔离配置,深度剖析JEP 477 ScopedValue与CarrierThread绑定机制

第一章:Java 25虚拟线程资源隔离配置概览Java 25正式将虚拟线程(Virtual Threads)纳入长期支持特性,并强化了其在高并发场景下的资源隔离能力。虚拟线程本身轻量、按需调度,但若缺乏显式资源约束,仍可能因共…...

Qwen3-VL-4B-Instruct:多模态视觉语言模型的技术演进与实践指南

Qwen3-VL-4B-Instruct:多模态视觉语言模型的技术演进与实践指南 【免费下载链接】Qwen3-VL-4B-Instruct 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/Qwen3-VL-4B-Instruct 技术突破:重新定义多模态交互范式 Qwen3-VL-4B-Instruct作为…...

内核热补丁和function trace的兼容性浅析

本文代码基于linux内核4.19.195. 之前的文章简要讲解了内核热补丁的原理,也提到了热补丁是基于ftrace框架实现的。平时我们在用ftrace时,最常用的功能当属function tracer了。这天一个有趣的问题突然浮现在我的脑海里: 如果我对同一个函数&am…...

如何保证代码质量?

一、编码阶段:从源头控制质量1. 统一代码规范(强制执行)核心目标:减少风格差异,提高可读性常见工具:ESLint:代码规范校验Prettier:自动格式化Stylelint:样式规范&#x1…...

3大突破!LxgwWenKai字体效率革命:从代码阅读到多场景适配全指南

3大突破!LxgwWenKai字体效率革命:从代码阅读到多场景适配全指南 【免费下载链接】LxgwWenKai LxgwWenKai: 这是一个开源的中文字体项目,提供了多种版本的字体文件,适用于不同的使用场景,包括屏幕阅读、轻便版、GB规范字…...

如何用ViGEmBus实现Windows内核级游戏手柄模拟:架构解析与实践指南

如何用ViGEmBus实现Windows内核级游戏手柄模拟:架构解析与实践指南 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus ViGEmBus是一款Windows内核模…...

Llama-3.2V-11B-cot多场景:科研论文插图理解、工程图纸解析、UI截图分析

Llama-3.2V-11B-cot多场景应用:科研论文插图理解、工程图纸解析、UI截图分析 1. 模型概述 Llama-3.2V-11B-cot是一款基于LLaVA-CoT论文实现的视觉语言模型,具备强大的图像理解和系统性推理能力。该模型采用MllamaForConditionalGeneration架构&#xf…...

卡证检测矫正模型效果展示:高清四角点定位+正视角矫正图实拍

卡证检测矫正模型效果展示:高清四角点定位正视角矫正图实拍 你有没有遇到过这样的烦恼?需要上传身份证、驾照或者护照照片时,手机随手一拍,结果照片歪歪扭扭,背景杂乱,关键信息还被手指挡住了。这时候要么…...

RexUniNLU案例集:制造业设备报修场景中,‘异响’‘漏油’‘停机’故障标签识别效果

RexUniNLU案例集:制造业设备报修场景中,‘异响’‘漏油’‘停机’故障标签识别效果 1. 引言:当设备“说话”时,我们如何听懂? 想象一下这个场景:在一条繁忙的生产线上,一台关键设备突然发出“…...

STM32一键下载电路设计与CH340应用

STM32一键下载电路设计与实现1. 项目概述1.1 功能需求STM32系列微控制器在开发过程中,通常需要通过串口进行程序下载。传统下载方式需要手动操作BOOT0和RESET引脚,过程繁琐且容易出错。本项目设计了一种基于CH340芯片的自动下载电路,通过软件…...

突破学术写作瓶颈:WPS-Zotero革新文献管理工作流

突破学术写作瓶颈:WPS-Zotero革新文献管理工作流 【免费下载链接】WPS-Zotero An add-on for WPS Writer to integrate with Zotero. 项目地址: https://gitcode.com/gh_mirrors/wp/WPS-Zotero 在学术写作的征途上,文献管理如同隐形的绊脚石&…...

USBToolBox高效管理实战指南:多设备USB映射自动化配置全流程

USBToolBox高效管理实战指南:多设备USB映射自动化配置全流程 【免费下载链接】tool the USBToolBox tool 项目地址: https://gitcode.com/gh_mirrors/too/tool 在现代多设备办公环境中,USB映射(将物理USB端口映射为系统可识别的逻辑设…...