双指针算法:从原理到实战,搞定数组_字符串高频题 📅 发布时间:2026/7/9 11:12:41 👁️ 浏览次数: 双指针算法从原理到实战搞定数组/字符串高频题在算法世界中双指针是一种简单却极具威力的优化思想。它通过两个指针的协同移动将暴力解法的O(n2)O(n^2)O(n2)时间复杂度优化到O(n)O(n)O(n)尤其适用于数组、字符串、链表等线性数据结构的问题。本文将基于「比特就业课」优选算法精品课的双指针内容从核心原理、常见类型到经典实战例题带你彻底吃透双指针算法。一、双指针算法核心原理双指针的核心思想是用两个指针遍历数据结构通过指针的移动规则减少不必要的遍历。不同于暴力解法的嵌套循环双指针仅需一次或两次线性遍历即可完成任务本质是利用数据的有序性、连续性等特性缩小查找或处理的范围。双指针的关键在于确定指针的初始位置如数组两端、起始位置定义指针的移动规则如向中间靠拢、一快一慢、同向移动明确算法的终止条件如指针相遇、指针越界。二、双指针的三大常见类型根据指针的移动方式双指针主要分为「对撞指针」「快慢指针」和「数组划分指针」三类每类都有其典型应用场景。1. 对撞指针左右指针核心特点指针起始位置数组/字符串的两端left0rightn-1移动方向向中间靠拢终止条件left right指针相遇或 left right指针错开适用场景有序数组/字符串的查找、区间最值、两数/三数之和等问题。核心原理对撞指针利用数据的有序性或特定分布特性每次移动一个指针就能排除一部分无效区间。例如在有序数组中通过比较左右指针指向元素的和与目标值的大小可快速缩小查找范围。2. 快慢指针龟兔赛跑算法核心特点指针起始位置通常都在数组/链表的起始位置slow0fast0移动方向同向移动但速度不同如慢指针走1步快指针走2步终止条件快指针到达数据末尾、快慢指针相遇检测循环适用场景环形结构检测、链表中点查找、数组中重复元素处理、快乐数等存在循环的问题。核心原理快慢指针的核心是利用「速度差」制造距离。例如在环形链表中快指针最终会追上慢指针在数组去重中快指针负责遍历元素慢指针负责标记有效位置。3. 数组划分指针核心特点指针起始位置一个指针cur从起始位置遍历另一个指针dest标记目标区间边界如非零元素末尾移动方向同向移动cur 负责遍历dest 负责定位终止条件cur 遍历完整个数组适用场景数组按条件划分如移动零、复写零、元素分类等问题。核心原理通过两个指针划分数组区间例如将数组分为「非零元素区」和「零元素区」cur 遍历过程中不断扩大目标区间dest 始终指向目标区间的末尾。三、经典实战例题从基础到进阶下面结合 LeetCode 高频题详解各类双指针的应用的每道题均附核心思路和代码实现。例题1移动零Easy数组划分指针题目链接283. 移动零题目描述给定一个数组nums将所有 0 移动到数组末尾保持非零元素的相对顺序要求原地操作。示例输入nums [0,1,0,3,12]输出[1,3,12,0,0]核心思路利用「数组划分」思想用两个指针划分区间cur遍历整个数组寻找非零元素dest标记非零元素区间的最后一个位置初始为 -1表示暂无非零元素规则当nums[cur] ! 0时dest先向后移动一位扩大非零区间再交换nums[cur]和nums[dest]当nums[cur] 0时cur直接向后移动零元素自动归入另一区间最终效果[0, dest]为非零元素区间[dest1, cur-1]为零元素区间。Java 代码实现class Solution { public void moveZeroes(int[] nums) { for(int cur 0, dest -1; cur nums.length; cur) { if(nums[cur] ! 0) { // 仅处理非零元素 dest; // 非零区间扩大一位 // 交换cur和dest位置的元素 int tmp nums[cur]; nums[cur] nums[dest]; nums[dest] tmp; } } } }性能表现时间复杂度O(n)O(n)O(n)仅一次遍历空间复杂度O(1)O(1)O(1)原地操作执行结果Java 代码耗时 1ms击败 100% 提交。例题2盛最多水的容器Medium对撞指针题目链接11. 盛最多水的容器题目描述给定一个整数数组height表示 n 条垂线的高度找出两条垂线使其与 x 轴构成的容器能容纳最多的水不能倾斜容器。示例输入height [1,8,6,2,5,4,8,3,7]输出49核心思路容器的容积由「短板高度」和「指针间距」决定容积 指针间距 * min(左板高度, 右板高度)。利用对撞指针优化初始位置left0左端点rightheight.length-1右端点移动规则若height[left] height[right]左板是短板移动左指针left因为移动右指针只会让容积变小间距减小短板不变否则右板是短板移动右指针right--终止条件left right遍历过程中记录最大容积。Java 代码实现class Solution { public int maxArea(int[] height) { int left 0, right height.length - 1, maxVol 0; while(left right) { // 计算当前容积 int vol Math.min(height[left], height[right]) * (right - left); maxVol Math.max(maxVol, vol); // 移动短板指针 if(height[left] height[right]) left; else right--; } return maxVol; } }性能表现时间复杂度O(n)O(n)O(n)一次遍历空间复杂度O(1)O(1)O(1)执行结果Java 代码耗时 4ms击败 60.7% 提交。例题3快乐数Medium快慢指针题目链接202. 快乐数题目描述「快乐数」定义对于正整数 n每次将其替换为每个位置上数字的平方和重复该过程若最终能得到 1 则为快乐数若无限循环则不是。示例输入n19输出true19→82→68→100→1核心思路快乐数的关键是判断「是否存在循环」若存在循环且循环节点不是 1则不是快乐数利用快慢指针检测循环慢指针slow每次执行 1 次平方和操作快指针fast每次执行 2 次平方和操作终止条件快慢指针相遇若相遇时的值为 1则是快乐数否则不是快指针先到达 1直接返回 true。辅助函数计算数字的平方和private int bitSum(int n) { int sum 0; while(n ! 0) { int t n % 10; // 提取个位 sum t * t; n / 10; // 移除个位 } return sum; }Java 代码实现class Solution { public boolean isHappy(int n) { int slow n, fast bitSum(n); while(slow ! fast) { slow bitSum(slow); // 慢指针走1步 fast bitSum(bitSum(fast)); // 快指针走2步 } return slow 1; // 相遇时是否为1 } private int bitSum(int n) { int sum 0; while(n ! 0) { int t n % 10; sum t * t; n / 10; } return sum; } }性能表现时间复杂度O(logn)O(log n)O(logn)每次平方和操作会减少数字位数空间复杂度O(1)O(1)O(1)执行结果Java 代码耗时 0ms击败 100% 提交。例题4三数之和Medium对撞指针排序题目链接15. 三数之和题目描述给你一个整数数组nums找出所有和为 0 且不重复的三元组i≠j≠k。示例输入nums [-1,0,1,2,-1,-4]输出[[-1,-1,2],[-1,0,1]]核心思路三数之和可转化为「固定一个数 两数之和」利用排序对撞指针优化排序先对数组排序便于去重和双指针查找固定数a遍历数组固定nums[i]为a目标转化为在i1到n-1区间找两个数使其和为-a对撞指针lefti1rightn-1查找两数之和去重固定数a去重若nums[i] nums[i-1]跳过避免重复三元组双指针去重找到有效三元组后left和right分别跳过重复元素。Java 代码实现import java.util.ArrayList; import java.util.Arrays; import java.util.List; class Solution { public ListListInteger threeSum(int[] nums) { ListListInteger result new ArrayList(); Arrays.sort(nums); // 排序 int n nums.length; for(int i 0; i n; ) { if(nums[i] 0) break; // 优化a0时三数和不可能为0 int target -nums[i]; int left i 1, right n - 1; while(left right) { int sum nums[left] nums[right]; if(sum target) { right--; } else if(sum target) { left; } else { // 找到有效三元组 result.add(new ArrayList(Arrays.asList(nums[i], nums[left], nums[right]))); left; right--; // 双指针去重 while(left right nums[left] nums[left-1]) left; while(left right nums[right] nums[right1]) right--; } } // 固定数a去重 i; while(i n nums[i] nums[i-1]) i; } return result; } }性能表现时间复杂度O(n2)O(n^2)O(n2)排序O(nlogn)O(n log n)O(nlogn) 遍历双指针O(n2)O(n^2)O(n2)空间复杂度O(logn)O(log n)O(logn)排序所需空间执行结果Java 代码耗时 26ms击败 98.56% 提交。四、双指针算法解题技巧总结先判断数据特性有序数组优先考虑对撞指针环形问题优先快慢指针数组划分问题用同向双指针注重边界处理避免指针越界如right nums.length - 1、重复元素去重三数之和、两数之和学会问题转化将三数之和转化为两数之和将快乐数循环检测转化为快慢指针相遇问题原地操作优先双指针算法的核心优势之一是原地操作减少额外空间开销如移动零、复写零多练习找规律双指针的移动规则虽灵活但同类题目有固定套路多做例题就能快速上手。五、总结双指针算法是优化线性数据结构问题的“利器”其核心是通过指针的协同移动减少无效遍历。无论是简单的移动零、盛最多水的容器还是中等难度的快乐数、三数之和掌握双指针的三类核心类型和解题技巧就能高效解决这类高频题。建议大家结合本文的例题反复练习重点体会“指针移动规则”的设计思路再尝试独立解决同类题目如四数之和、有效三角形的个数相信你能快速掌握双指针算法的精髓如果需要进一步巩固可以尝试用双指针解决「复写零」「和为s的两个数字」等题目检验自己的学习成果~
关于三角洲反作弊cpu虚拟化和电脑wsl使用冲突问题的解决方案 问题 笔者电脑中使用wsl2进行日常开发,同时也会玩三角洲,但是昨日玩三角洲弹出下图弹框然后闪退首先在任务管理器的性能界面可以看到我是打开了cpu虚拟化的然后根据官方文档,要求关闭Hyper-V,在powershell以管理员身份打开&#x… 2026/5/17 10:21:41
TIDB分布式数据库 概念 TiDB 是一款开源的分布式 NewSQL 数据库,兼容 MySQL 生态,支持水平扩展、金融级高可用及实时 HTAP(混合事务分析处理)。与 OldSQL(如 MySQL)相比,它解决了单机容量和性能瓶颈;与… 2026/7/8 21:27:25
上下文管理艺术:突破 Token 限制 上下文管理艺术:突破 Token 限制 🎯 学习目标 掌握长文档处理的三种核心策略学会设计记忆机制和对话管理系统理解 RAG(检索增强生成)的实战应用能够构建万字长文自动生成系统 📖 核心概念 Token 限制的困境 现状&… 2026/5/17 10:21:39
从一次交付到长期合作,IACheck AI报告审核通审Agent版如何助力检测机构构建报告质量信任体系 在检测行业中,客户选择一家检测机构,往往并不仅仅取决于检测价格、服务速度或者设备能力,更重要的是长期合作过程中,机构能否持续输出稳定、规范、可信的检测报告。对于企业客户而言,一份检测报告不仅是检测结果的载体… 2026/7/9 11:12:39
终极老旧Mac升级实战:OpenCore Legacy Patcher深度解析与应用指南 终极老旧Mac升级实战:OpenCore Legacy Patcher深度解析与应用指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否拥有一台被苹果官方抛弃的… 2026/7/9 11:10:38
Misc-隐藏的小猫(图片隐写) 1. 题目基本信息题型:Misc 杂项(最简单文件隐写)难度:⭐ 入门送分题题目描述:图片里藏了秘密flag,看看图片底层有什么?附件:cat.pngFlag格式:flag{xxx}解题环境ÿ… 2026/7/9 11:08:37
带你了解PD-L1 PD-L1抗体的分子特性与免疫调控机制PD-L1(程序性死亡配体1,又称B7-H1或CD274)是一种I型跨膜糖蛋白,由290个氨基酸组成,属于B7共刺激分子家族的重要成员。其结构包含胞外免疫球蛋白可变区(IgV-like domain&a… 2026/7/9 11:06:36
STM32与欧姆龙G6D-ASI实现直流负载智能管理方案 1. 项目背景与核心需求在工业自动化与电力电子领域,直流负载管理一直是系统设计的关键痛点。传统机械式继电器在频繁开关场景下存在触点磨损、响应延迟等问题,而普通电子开关又难以兼顾大电流承载与精确控制。这个项目正是针对这一行业难题,采… 2026/7/9 11:04:35
锂离子电池电压平衡技术及STM32实现方案 1. 锂离子电池电压平衡的必要性 在串联连接的锂离子电池组中,电压不平衡是一个常见但危险的问题。当两节或多节电池串联使用时,即使使用同一批次的全新电池,随着充放电循环次数的增加,各单体电池的电压也会逐渐出现差异。这种差异… 2026/7/9 11:04:35
机器视觉与PLC集成:轮毂缺陷检测与字符识别误差控制在0.2mm内 机器视觉与PLC集成:轮毂缺陷检测与字符识别误差控制在0.2mm内的技术实现轮毂作为汽车关键零部件,其表面质量直接影响行车安全与美观。传统人工检测效率低且易漏检,而采用机器视觉与PLC集成方案可实现微米级精度检测。本文将深入解析高精度视觉… 2026/7/9 0:01:04
GBase 8a vs MySQL 8.0:ALTER TABLE语法与限制的5点关键差异对比 GBase 8a与MySQL 8.0:ALTER TABLE语法差异深度解析与实战指南1. 两种数据库的ALTER TABLE能力全景对比在数据库架构设计和运维过程中,表结构变更(DDL操作)是不可避免的需求。GBase 8a作为国产分析型数据库代表,与开源M… 2026/7/9 0:03:06
【大数据毕业设计】基于多源旅游数据的景区热度分析与推荐系统的设计与实现 基于 Django 的旅游偏好挖掘与景区推荐系统(源码+文档+远程调试,全bao定制等) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am… 2026/7/9 0:05:09
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/7 11:26:57
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/8 20:15:17
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/8 14:25:08