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

数组算法-双指针

首先,双指针法,本质是通过两个索引(指针)在数组上移动,用一次遍历(O (n) 时间复杂度)替代嵌套循环(O (n²)),核心是用空间换时间(仅额外使用两个变量,空间复杂度 O (1))。

指针的移动规则根据问题场景而定,但核心都是:通过指针的协作,缩小处理范围,避免重复计算


1.左右指针(左 = 0,右 = len-1,向中间相遇)

1.适用:数组有序或 问题具有对称性,无需遍历所有元素,通过两端收缩即可找到解。

  • 数组 / 字符串的对称操作:反转数组、反转字符串、判断回文数 / 回文字符串

  • 有序数组的两数之和:找两个数和为目标值(LeetCode LCR 006,167)

  • 有序数组的区间收缩:最接近目标值的两数之和、两数之差等于目标值

2.循环条件:left < right(无需<=,相遇即终止)

3.移动规则:根据条件单向移动(左指针右移增大值,右指针左移减小值)

例 1:

我们分析题目信息发现“数组有序”“要找两数之和为目标数”,那么就可以使用左右指针解答:

intleft=0,right=numbers.length-1;while(left<right){if(numbers[left]+numbers[right]>target){right--;}elseif(numbers[left]+numbers[right]<target){left++;}else{break;}}returnnewint[]{left,right};

最后我们还要注意边界校验,此题告诉我们一定存在结果,追求简洁可不加;但通常我们还要加上:

if (numbers == null || numbers.length < 2) return new int[]{-1, -1};表示无结果

2.快慢指针(慢指针定有效边界,快指针遍历全数组,同向移动)

1.适用:需要原地修改数组,需筛选 / 保留有效元素,剔除无效元素(重复、指定值、0 值等)。

  • 有序数组去重(LeetCode 26)
  • 移除数组中指定值的元素(LeetCode 27)
  • 移动数组中的 0 到末尾(保留非 0 元素的相对顺序)
  • 筛选数组中的有效元素(如只保留偶数、只保留正数)

2.循环条件:fast < nums.length(快指针遍历完数组即终止)

3.移动规则:快指针找到有效元素时,慢指针先右移(扩大有效区域)再赋值覆盖,否则快指针单独右移

4.结果返回:slow + 1(慢指针是索引,有效数组长度 = 索引 + 1)

例 2:

我们看题干中出现”非严格递增排列“,”原地删除“和”只出现一次“的字样,确定此题属于有序数组去重,可以使用快慢指针解题:

intslow=0;for(intfast=1;fast<nums.length;fast++){if(nums[slow]!=nums[fast]){slow++;nums[slow]=nums[fast];}}returnslow+1;

例 3:

先分析题干“原地”,“移除指定值”,可以使用快慢指针解题:

intslow=0;for(intfast=0;fast<nums.length;fast++){if(nums[fast]!=val){nums[slow]=nums[fast];slow++;}}returnslow;

3. 滑动窗口(动态快慢指针,形成可变窗口,同向移动)

1.适用:子串的最值(最长 / 最短)、满足条件的子数组(和≥目标值、和为 k、无重复元素),问题聚焦连续区间的筛选

  • 长度最小的子数组(和≥目标值,LeetCode209)
  • 最长无重复元素的子数组
  • 固定长度子数组的最大和 / 最小和
  • 子数组的和等于 k 的最短长度

2.循环条件:fast < nums.length(右指针遍历完数组即终止)

3.左指针:窗口左边界(控制窗口收缩)

4.右指针:窗口右边界(控制窗口扩大)

5.核心逻辑:右指针扩大窗口找解,左指针收缩窗口优化解

例 4:

求子数组,这是一个带条件(sum>=target) 的连续区间,即可以使用滑动窗口解题:

if(nums.length==0||nums==null)return0;intsum=0;intminLen=Integer.MAX_VALUE;intleft=0;for(intright=0;right<nums.length;right++){sum+=nums[right];while(sum>=target){minLen=Math.min(minLen,right-left+1);sum-=nums[left];left++;}}returnminLen==Integer.MAX_VALUE?0:minLen;
  1. 思路:第一步数组求和,第二步要求和值大于等于target的情况下缩短有效窗口的长度使其长度最小
  2. 我们照常声明左右指针都为0,通过右指针扩大右边界来遍历数组求和sum
  3. sum >= target时,就可以通过左指针循环收缩左边界,直到不满足条件
  4. 同时每次达到条件都可以将此时的长度赋值给minLen并保持最小
    缩短有效窗口的长度使其长度最小
  5. 最后考虑特殊情况,如果在右指针遍历的全过程中没有一次满足条件,则minLen == Integer.MAX_VALUE,即不存在符合条件的子数组返回 0
http://www.jsqmd.com/news/283583/

相关文章:

  • 基于Python + Django物业管理系统(源码+数据库+文档)
  • 基于Python 个性化餐饮管理系统(源码+数据库+文档)
  • 智慧交通数据治理中的典型“四重困境”:**异构性、时效性、关联性、质量性**四大瓶颈,共同导致数据价值难以释放
  • 驾校管理|基于springboot + vue驾校管理系统(源码+数据库+文档)
  • 要落实国家“人工智能+”行动与“数据要素×”三年行动计划并打造数智化发展新高地
  • 通过华为账号识别用户风险,降低业务损失
  • 基于Python 图书管理系统(源码+数据库+文档)
  • 【大数据毕设全套源码+文档】基于Django+协同过滤算法的电影个性化推荐系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 数据作为新型生产要素,正深刻推动各产业数字化转型与智能化升级
  • 揭秘气相毛细柱行业十大品牌:生产厂家综合实力排行榜
  • 快速验证:用中文Cursor一小时打造天气APP
  • 2026成都装修公司哪家好?实测口碑装修公司+选装攻略,新手装修省心装
  • MySQL LIMIT在电商系统中的5个实战应用
  • RAG性能瓶颈突破:文档切分的核心逻辑与最优实践
  • 【大数据毕设全套源码+文档】基于Djangod+协同过滤算法的经济型酒店推荐系统大数据的设计与实现(丰富项目+远程调试+讲解+定制)
  • 我把pdfplumber整成了可以拖拉拽的web应用
  • 2026五大成都优质装修机构盘点
  • 双击轻捏,手写笔交互丝滑切换
  • 基于Python + Django个性化餐饮管理系统(源码+数据库+文档)
  • 用JDK1.7快速构建原型:Web服务示例
  • SQL和Python 哪个更容易自学?
  • 通义千问模型部署新玩法:语音输入生成萌宠图片教程
  • 2026现代装修全案公司揭晓!谁是你的梦中情“装”?
  • 了解Agent Skills,这一篇就够了
  • 1小时搞定:用PLAYWRIGHT快速验证产品创意
  • 林业资源管理|基于java + vue林业资源管理系统(源码+数据库+文档)
  • 基于Python + Django图书管理系统(源码+数据库+文档)
  • CentOS包管理器(dnf)
  • 情绪宣泄平台系统|基于java+ vue情绪宣泄平台系统(源码+数据库+文档)
  • nTopology平台自动生成适配不同热源分布的流道拓扑。