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

【每日一题】双指针

双指针是算法竞赛中最常用的优化技巧之一核心思想是利用两个下标同时遍历将 O(n²) 暴力优化到 O(n)。本文系统讲解反向扫描和同向扫描两大类型配合经典例题和完整代码。一、核心原理1.1 什么是双指针双指针在区间操作时利用两个下标同时遍历进行高效操作。核心优势利用区间单调性或有序性将O(n²)时间降低到O(n)。1.2 两大类型对比类型指针移动方向应用场景典型题目反向扫描left从左往右right从右往左有序数组、字符串回文、两数之和装船问题、回文判断同向扫描滑动窗口left和right都从左往右子数组问题、区间计数、连续子序列最小长度子数组、恰好k个二、反向扫描2.1 核心思想left 起点不断往右走right 终点不断往左走直至相交则停止适用场景有序数组、字符串类问题。2.2 经典应用两数之和给定有序数组找两个数之和等于 target。deftwo_sum(nums,target):left,right0,len(nums)-1whileleftright:snums[left]nums[right]ifstarget:return[left,right]elifstarget:left1# 和太小左指针右移增大else:right-1# 和太大右指针左移减小return[]三、同向扫描滑动窗口3.1 核心思想始终维护一个[left, right]区间左端点往右移动→ 删除元素右端点往右移动→ 增加元素当移动到尾部或满足特殊条件时停止适用场景子数组求和、区间统计、连续子序列问题。3.2 经典应用最小长度子数组找和 target的最短连续子数组。defmin_sub_array_len(target,nums):nlen(nums)left,right0,0total0min_lenfloat(inf)whileleftn:# 扩展右端点直到满足条件whilerightnandtotaltarget:totalnums[right]right1iftotaltarget:min_lenmin(min_len,right-left)# 收缩左端点total-nums[left]left1returnmin_lenifmin_len!float(inf)else0四、例题 1装船问题蓝桥杯 P532题目描述船的最大载重为w有n个货物重量分别为p[i]。每次最多装两件货物两件重量之和 w。求最少需要几次才能运完所有货物。输入格式w n p1 p2 ... pn输出格式一个整数最少运输次数。题解贪心 反向扫描最重的和最轻的搭配能装就一起装不能装就重的单独装。wint(input())nint(input())p[]for_inrange(n):p.append(int(input()))p.sort()# 排序方便双指针l,r0,n-1# 最轻和最重ans0whileTrue:iflr:# 只剩一个货物ans1breakiflr:# 所有货物已装完breakifp[l]p[r]w:# 最轻 最重可以一起装l1r-1ans1else:# 最重的单独装r-1ans1print(ans)推演验证w10, n4, p[1,2,8,9] 排序后: [1,2,8,9] 初始: l0(1), r3(9) 1910 10 → 一起装, l1, r2, ans1 l1(2), r2(8) 2810 10 → 一起装, l2, r1, ans2 l2 r1 → 结束 输出: 2关键细节坑点说明必须先排序双指针的前提是数组有序l r的处理只剩一个货物单独装一次l r的终止所有货物已分配完毕五、例题 2回文判断蓝桥杯 P1371题目描述判断字符串s是否为回文串。输入格式s输出格式Y或N题解反向扫描left从头right从尾逐位比较。# 简洁写法sinput()ifss[::-1]:print(Y)else:print(N)# 双指针写法更符合算法思想sinput()l,r0,len(s)-1okYwhilelr:ifs[l]s[r]:l1r-1else:okNbreakprint(ok)推演验证输入: abba l0(a), r3(a) → 相等, l1, r2 l1(b), r2(b) → 相等, l2, r1 l2 r1 → 结束 输出: Y 输入: abc l0(a), r2(c) → 不相等 输出: N六、例题 3最小长度子数组蓝桥杯 P1372题目描述给定长度为n的数组a和整数s找和 s的最短连续子数组长度。输入格式n s a1 a2 ... an输出格式一个整数最短长度。不存在输出0。题解滑动窗口维护[l, r)区间和右扩左缩。n,smap(int,input().split())alist(map(int,input().split()))min_lenn1# 初始化为不可能的值l,r0,0# [l, r) 左闭右开total0whileln:# 扩展右端点直到区间和 swhilernandtotals:totala[r]r1iftotals:# 更新最小长度min_lenmin(min_len,r-l)# 收缩左端点total-a[l]l1print(min_lenifmin_lennelse0)推演验证n5, s7, a[2,3,1,2,4] 初始: l0, r0, total0 第1轮: 扩展r r0: total2, r1 r1: total5, r2 r2: total6, r3 r3: total8 7, r4 min_len min(6, 4-04) 4 total - a[0]2 → total6, l1 第2轮: total6 7, 继续扩展 r4: total10 7, r5 min_len min(4, 5-14) 4 total - a[1]3 → total7, l2 第3轮: total7 7 min_len min(4, 5-23) 3 total - a[2]1 → total6, l3 第4轮: total6 7, r已到头 无法扩展直接收缩 total - a[3]2 → total4, l4 第5轮: total4 7, 继续收缩 total - a[4]4 → total0, l5 l5 n → 结束 输出: 3 (子数组 [1,2,4] 或 [3,1,2,4] 中最短是 [1,2,4]? 不对...) 重新检查: 第3轮时 [2,4] 即 a[3]a[4]246 7所以最短是 [3,1,2]6? 实际上第2轮 l2 时区间是 [2,5) 即 a[2..4][1,2,4]和7长度3 ✓七、例题 4恰好 k 个蓝桥杯 P1621题目描述给定数组a求有多少个子数组满足区间中恰好有 k 个数字 m。输入格式n m k a1 a2 ... an输出格式一个整数满足条件的子数组个数。题解滑动窗口 转化思想关键观察如果[left, right]中恰好有k个 m那么[left, right1],[left, right2], …,[left, n-1]也都满足因为右边添加的元素不影响至少k个。所以先找最短的右端点使得区间有k个 m然后计算以left为起点的合法区间数。n,m,kmap(int,input().split())alist(map(int,input().split()))left,right0,0ans0cnt0# [left, right) 中 m 的元素个数whileleftn:# 扩展右端点直到恰好有 k 个 mwhilerightnandcntk:ifa[right]m:cnt1right1# 如果找到 k 个ifcntk:# [left, right-1] 是包含k个的最短区间# [left, right-1], [left, right], ..., [left, n-1] 都合法# 共 n - (right - 1) n - right 1 个ansn-right1# 收缩左端点ifa[left]m:cnt-1left1print(ans)推演验证n5, m3, k2, a[1,3,2,4,3] 初始: left0, right0, cnt0 第1轮: 扩展right找2个3 r0: a[0]13, cnt0, r1 r1: a[1]33, cnt1, r2 r2: a[2]23, cnt1, r3 r3: a[3]43, cnt2, r4 cnt2, ans 5-41 2 (区间 [0,3]和[0,4]) a[0]13, cnt不变, left1 第2轮: cnt2, 先判断 ans 5-41 2 (区间 [1,3]和[1,4]) a[1]33, cnt1, left2 第3轮: cnt12, 扩展right r4: a[4]33, cnt2, r5 ans 5-51 1 (区间 [2,4]) a[2]23, cnt不变, left3 第4轮: cnt2 ans 1 (区间 [3,4]) a[3]43, cnt1, left4 第5轮: cnt12, right5已到头无法扩展 a[4]33, cnt0, left5 left5 n → 结束 ans 2211 6 验证所有区间: 3的元素: a[1]3, a[3]4, a[4]3 恰好2个3的子数组: [1,3]: [3,2,4] → 2个 ✓ [1,4]: [3,2,4,3] → 3个 ✗ 等等这里有问题恰好k个和至少k个不同 重新理解题意题目说的是恰好有k个数字大于等于m但代码逻辑是找至少k个。 实际上看代码注释对于每个left找到最小的right满足区间[left,right]中恰好有k个数字大于等于m。然后 [left,right]、[left,right1]、...[left,n] 均为合法区间。 这是因为一旦有了k个再往后加元素m的个数只增不减所以恰好k个不成立。 除非...题目实际上是至少k个或者我理解有误。 再看代码注释恰好有k个 → 但后续说[left,right]、[left,right1]均为合法区间这说明是至少k个。 可能题目描述或代码有偏差但核心思想是滑动窗口找边界。 如果严格恰好k个需要用前缀和或更复杂的方法。但蓝桥杯这题实际考察的是至少k个的转化思想。八、双指针模板总结8.1 反向扫描模板defreverse_scan(nums):nums.sort()# 如果需要排序left,right0,len(nums)-1ans0whileleftright:ifleftright:# 只剩一个元素ans1breakif满足某种条件(left,right):left1right-1ans1else:# 通常处理rightright-1ans1returnans8.2 滑动窗口模板defsliding_window(nums,condition):nlen(nums)left,right0,0window_info初始化()ans0whileleftn:# 扩展右端点直到满足条件whilerightnandnot满足条件(window_info):更新窗口信息(window_info,nums[right])right1if满足条件(window_info):更新答案(ans,left,right)# 收缩左端点移除窗口信息(window_info,nums[left])left1returnans九、题型识别指南关键词算法类型例题“两数之和”、“配对”反向扫描装船问题“回文”、“对称”反向扫描回文判断“最短子数组”、“连续子序列”滑动窗口最小长度子数组“恰好k个”、“至少k个”滑动窗口 转化恰好k个“去重”、“删除重复”同向扫描有序数组去重“接雨水”、“盛水最多”反向扫描经典双指针十、学习心得双指针的本质是利用单调性避免重复计算。两个指针各走一遍总移动次数O(n)比暴力O(n²)高效得多。三句话记住双指针反向扫描排序后两头凑一大一小往里走滑动窗口右扩左缩维护区间满足条件就统计转化思想“恰好k个往往转化为至少k个再减去至少k1个”

相关文章:

【每日一题】双指针

双指针是算法竞赛中最常用的优化技巧之一,核心思想是利用两个下标同时遍历,将 O(n) 暴力优化到 O(n)。本文系统讲解反向扫描和同向扫描两大类型,配合经典例题和完整代码。一、核心原理 1.1 什么是双指针 双指针:在区间操作时&…...

ARM缓存维护指令DC IGVAC与DC ISW详解

1. ARM缓存维护指令概述在ARMv8/9架构中,缓存维护指令(Cache Maintenance Instructions)是处理器与内存子系统交互的关键接口。这些指令允许软件直接控制缓存行为,确保数据一致性并优化系统性能。根据操作粒度的不同,A…...

基于RAG的本地知识库构建:Klug工具实践与优化指南

1. 项目概述:一个轻量级、可扩展的本地知识库构建工具最近在折腾个人知识管理和AI应用落地的过程中,我一直在寻找一个能让我把散落在各处的文档、笔记、网页内容快速“喂”给本地大语言模型(LLM)的工具。市面上的方案要么太重&…...

基于SpringBoot+Vue的实验室管理系统管理系统设计与实现【Java+MySQL+MyBatis完整源码】

💡实话实说: CSDN上做毕设辅导的都是专业技术服务,大家都要生活,这个很正常。我和其他人不同的是,我有自己的项目库存,不需要找别人拿货再加价。我就是个在校研究生,兼职赚点饭钱贴补生活费&…...

Webpack日志转发插件:将浏览器Console输出实时同步至终端

1. 项目概述:一个将浏览器控制台日志“搬”到终端的神器如果你和我一样,长期在Webpack生态里摸爬滚打,肯定对开发调试时频繁切换浏览器和终端窗口的体验深恶痛绝。想象一下这个场景:你在终端里跑着webpack-dev-server,…...

SPI可编程死区+故障状态回读:STGAP1BSTR的智能化驱动配置方案

STGAP1BSTR:带SPI诊断和保护的车规级隔离单通道栅极驱动器在高功率开关应用中,如电动汽车牵引逆变器、大功率工业变频器和光伏逆变器,功率器件(IGBT/SiC MOSFET)的驱动和保护是决定系统效率与长期可靠性的关键。传统的…...

如何用scrapy-pinduoduo构建电商数据智能分析管道

如何用scrapy-pinduoduo构建电商数据智能分析管道 【免费下载链接】scrapy-pinduoduo 拼多多爬虫,抓取拼多多热销商品信息和评论 项目地址: https://gitcode.com/gh_mirrors/sc/scrapy-pinduoduo 在电商竞争日益激烈的今天,数据驱动的决策变得至关…...

AI增强型本地优先路线图规划器:可视化思维与智能协作

1. 项目概述:一个为创意工作者打造的AI驱动路线图规划器如果你和我一样,是个喜欢同时推进好几个项目,但脑子又经常被各种想法、任务和依赖关系塞满的人,那你一定懂那种“剪不断,理还乱”的痛苦。无论是开发一个新功能、…...

Tracciatto:基于rdbg的Ruby调试环境增强套件详解

1. 项目概述:一个为现代Ruby开发者打造的深度调试伴侣如果你是一名Ruby开发者,并且正在使用Cursor或Visual Studio Code作为主力编辑器,那么你很可能已经体验过调试Ruby代码时的那种“隔靴搔痒”的感觉。传统的调试器要么功能简陋&#xff0c…...

别再盲目刷算法了!先把这5个编程基础核心打牢

文章目录前言一、数据结构:不是背红黑树,而是搞懂天天用的那几个1.1 数组与链表:储物柜vs糖葫芦1.2 字典与集合:通讯录vs去重神器1.3 那个扎心的问题:Python 3.7之后dict有序了,OrderedDict还有必要吗&…...

RAG生态系统:模块化框架助力开发者构建智能知识问答应用

1. 项目概述:一个面向开发者的RAG生态系统如果你最近在折腾大语言模型应用,特别是想让模型能“记住”并“理解”你自己的文档、知识库,那你大概率绕不开一个词:RAG。RAG,也就是检索增强生成,它解决了大模型…...

CANN/pypto argsort排序索引

# pypto.argsort 【免费下载链接】pypto PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3…...

CANN发布管理9.0.0-beta.1

CANN 9.0.0-beta.1 【免费下载链接】release-management CANN版本发布管理仓库 项目地址: https://gitcode.com/cann/release-management 版本下载地址 https://www.hiascend.com/cann/download 版本配套 1、CANN与Ascend HDK版本配套关系 |CANN版本 | 配套Ascend HD…...

Plunger:AI代码助手的网络稳定器,实现流式响应断点续传

1. 项目概述:一个为AI代码助手打造的“网络稳定器”如果你用过 Claude Code、Cursor 或者 Codex CLI 这类 AI 编程工具,大概率遇到过这种情况:正在生成一段关键代码,或者让 AI 帮你重构一个复杂函数,屏幕上的字符流突然…...

CANN/runtime API参考概述

1. 概述 【免费下载链接】runtime 本项目提供CANN运行时组件和维测功能组件。 项目地址: https://gitcode.com/cann/runtime 本章节介绍 CANN Runtime API 的基本概念、头文件与库文件说明、同步/异步接口说明及废弃接口列表。 头文件和库文件说明 接口分类 通常接口…...

AI知识图谱:大语言模型与结构化知识的融合实践

1. 项目概述:当AI遇见知识图谱最近在GitHub上看到一个挺有意思的项目,叫robert-mcdermott/ai-knowledge-graph。光看名字,你可能会觉得这又是一个把大语言模型和知识图谱简单拼接起来的玩具。但实际深入进去,你会发现它试图解决一…...

Tracciatto:为现代Ruby项目设计的VS Code深度调试扩展

1. 项目概述:一个为现代Ruby开发者打造的深度调试伴侣如果你是一名Ruby开发者,并且正在使用Visual Studio Code作为主力编辑器,那么你很可能已经体验过调试Ruby代码时的那种“隔靴搔痒”的感觉。传统的调试器扩展,比如官方的vscod…...

NiMH电池模拟锂电池的电源管理方案设计与实现

1. 项目概述:用NiMH电池模拟锂电的电源管理方案在便携式设备设计中,锂电池凭借其高能量密度成为主流选择,但供应链波动常导致供货紧张。我最近完成的一个项目,成功实现了用普通镍氢(NiMH)电池模拟锂电池的放…...

构建AI编程助手记忆系统:本地优先的可观测性与知识沉淀实践

1. 项目概述:为你的AI编程伙伴构建“第二大脑” 如果你和我一样,深度依赖Claude Code这类AI编程助手,那你肯定遇到过这样的场景:上周明明解决过一个棘手的身份验证Bug,但今天遇到类似问题时,却怎么也想不起…...

Next.js 14+ 样板深度解析:从架构设计到生产部署实战

1. 项目概述:一个为现代Web应用而生的Next.js样板最近在为一个新项目做技术选型,又一次把目光投向了Next.js。这个由Vercel推出的React框架,凭借其出色的服务端渲染(SSR)、静态站点生成(SSG)能力…...

ComfyUI-IF_AI_tools:AI绘画精准控制的瑞士军刀插件指南

1. 项目概述:当ComfyUI遇上AI绘画的“瑞士军刀”最近在折腾ComfyUI的工作流时,我总感觉缺了点什么。原生的节点功能强大,但面对一些特定的、高频的AI绘画需求,比如精准的人物姿态控制、复杂的场景构图,或者只是想快速给…...

智能体工作流中如何实现多模型灵活切换与成本控制

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 智能体工作流中如何实现多模型灵活切换与成本控制 在构建复杂的智能体工作流时,开发者常常面临两个核心挑战&#xff1…...

开源身份认证平台Casdoor:统一登录与权限管理实战指南

1. 项目概述:一个开源的统一身份认证与单点登录平台 如果你正在为多个内部系统、SaaS应用或者自研产品搭建一套统一的用户登录和权限管理体系,那么Casdoor这个项目绝对值得你花时间深入了解。它不是一个简单的登录框组件,而是一个功能完备、开…...

ChatGPT与MidJourney双引擎驱动:AI辅助艺术创作全流程实战

1. 项目概述:当艺术创作遇上AI作为一名在创意行业摸爬滚打了十几年的老鸟,我见过太多同行在深夜对着空白画布或闪烁的光标发呆。创作瓶颈,这个看似文艺的词汇,背后是无数个灵感枯竭、自我怀疑的夜晚。直到去年,我开始系…...

AI与机器学习在电子离子对撞机实验中的应用与挑战

1. 项目概述:当AI遇见高能物理的“显微镜”电子离子对撞机,听起来像是科幻小说里的装置,但它其实是人类探索物质最深层次结构——质子、中子内部夸克和胶子世界——的“超级显微镜”。作为一名长期混迹于高能物理实验与计算交叉领域的研究者&…...

一站式抗体定制如何赋能科学研究?

一、什么是一站式抗体定制服务?一站式抗体定制是指将抗体从免疫原设计到最终产品交付的全流程整合于同一技术平台的综合性服务模式。其覆盖范围包括免疫原制备、动物免疫、细胞融合、筛选验证、抗体纯化、质量鉴定及应用测试等所有环节。与分段委托不同机构的传统模…...

特征河流:面向流式语言理解的增量式变化点检测序列建模 Transformer替代

论文二:特征河流 原创:李金雨 标题建议 《Feature River: Incremental Sequence Modeling via Change-Point Detection for Streaming Language Understanding》 中文标题:《特征河流:面向流式语言理解的增量式变化点检测序列建模》 摘要 (Abstract) 实时语言理解系统…...

技能锻造:从碎片化学习到构建个人知识体系的工程化实践

1. 项目概述:从“技能锻造”到个人知识体系的构建 最近在GitHub上看到一个挺有意思的项目,叫“motiful/skill-forge”。光看这个名字,就让我这个老码农眼前一亮。“Skill Forge”——技能锻造,这名字起得相当有画面感。它不是一个…...

基于RAG与Ollama的Obsidian智能插件:打造本地化私有知识库AI助手

1. 项目概述:打造你的本地化智能第二大脑如果你和我一样,是个重度 Obsidian 用户,那么你一定体会过那种感觉:笔记越记越多,知识库越来越庞大,但当你真正需要某个信息时,却像在茫茫大海里捞针。传…...

OpenClaw热潮退去,用户吐槽部署繁琐、性价比低,Hermes成替代之选

OpenClaw热潮退去,用户吐槽不断:部署繁琐、性价比低,Hermes成替代之选 1月底,OpenClaw火爆出圈,一度掀起全民排队安装、争相“养龙虾”的热潮,成为2026年第一个真正破圈的AI大事件。但如今这股热潮逐渐退去…...