news 2026/5/9 12:30:26

【算法】小白也能懂 · 第 2 节:数组双指针技巧(快慢指针、左右指针)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【算法】小白也能懂 · 第 2 节:数组双指针技巧(快慢指针、左右指针)

上一节讲了时间复杂度和空间复杂度,这一节来学一个在面试和竞赛中出场率极高的技巧——双指针。名字听起来很玄乎,其实思路非常简单:用两个变量(指针)在数组上移动,通过它们的配合来解决问题。

1. 什么是双指针

「指针」在这里不是 C 语言里的内存地址,而是一个形象的说法——它就是数组的下标(索引)。双指针就是同时用两个下标变量来遍历数组。

双指针有两种常见模式:

  • 快慢指针:两个指针从同一端出发,速度不同

  • 左右指针:两个指针分别从数组两端出发,向中间靠拢

下面分别来看。

2. 快慢指针

2.1 核心思路

快慢指针就像两个人在跑步——一个跑得快,一个跑得慢。通过观察它们的位置关系,可以发现一些有用的性质。

2.2 经典问题:删除有序数组中的重复项

题目:给定一个升序排列的数组nums,原地删除重复元素,使每个元素只出现一次,返回新数组的长度。

比如输入[1, 1, 2],处理后数组变成[1, 2, _],返回 2。

思路

  • 用一个「慢指针」slow标记当前不重复元素应该存放的位置

  • 用一个「快指针」fast去扫描整个数组

  • nums[fast] != nums[slow]时,说明遇到了新的不重复元素,把它放到slow + 1的位置

int removeDuplicates(vector<int>& nums) { if (nums.empty()) return 0; ​ int slow = 0; for (int fast = 1; fast < nums.size(); fast++) { if (nums[fast] != nums[slow]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; }

过程演示(以[1, 1, 2, 2, 3]为例):

初始: slow=0, fast=1 第 1 轮: nums[1]=1 == nums[0]=1,跳过 → slow=0, fast=2 第 2 轮: nums[2]=2 != nums[0]=1,slow++,赋值 → [1,2,2,2,3], slow=1, fast=3 第 3 轮: nums[3]=2 == nums[1]=2,跳过 → slow=1, fast=4 第 4 轮: nums[4]=3 != nums[1]=2,slow++,赋值 → [1,2,3,2,3], slow=2, fast=5 结束,返回 slow+1 = 3

时间复杂度 O(n),空间复杂度 O(1),非常高效。

2.3 经典问题:判断链表是否有环

虽然这道题用的是链表,但快慢指针的思想完全一样:

bool hasCycle(ListNode* head) { ListNode* slow = head; ListNode* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) return true; } return false; }

如果链表有环,快指针迟早会「追上」慢指针。如果没有环,快指针会先到达末尾。

3. 左右指针

3.1 核心思路

左右指针是两个指针分别指向数组的头和尾,然后根据条件向中间收缩。这种模式在有序数组上特别好用。

3.2 经典问题:两数之和(有序数组版本)

题目:给定一个升序数组nums和一个目标值target,找到两个数使它们的和等于target,返回它们的下标。

比如输入nums = [2, 7, 11, 15]target = 9,返回[0, 1](因为 2 + 7 = 9)。

思路

  • 左指针left指向数组开头,右指针right指向数组末尾

  • 计算sum = nums[left] + nums[right]

  • 如果sum == target,找到了,返回结果

  • 如果sum < target,说明和太小了,left++让和变大

  • 如果sum > target,说明和太大了,right--让和变小

vector<int> twoSum(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while (left < right) { int sum = nums[left] + nums[right]; if (sum == target) { return {left, right}; } else if (sum < target) { left++; } else { right--; } } return {}; }

为什么这个方法有效?因为数组是有序的。left右移会让和变大,right左移会让和变小。通过不断调整,两个指针最终会收敛到正确答案。时间复杂度 O(n)。

3.3 经典问题:盛最多水的容器

题目:给定n个非负整数height[0], height[1], ..., height[n-1],每个数代表坐标点(i, height[i])处的一条垂线。找两条线,使得它们与 x 轴围成的容器能盛最多的水。

思路

  • 左右指针分别指向头尾

  • 面积 =min(height[left], height[right]) * (right - left)

  • 移动较短的那一边的指针(因为移动较长的那边不可能让面积变大)

int maxArea(vector<int>& height) { int left = 0, right = height.size() - 1; int result = 0; while (left < right) { int area = min(height[left], height[right]) * (right - left); result = max(result, area); if (height[left] < height[right]) { left++; } else { right--; } } return result; }

4. 双指针的使用场景总结

模式适用场景典型题目
快慢指针检测环、去重、找中点有序数组去重、链表环检测
左右指针有序数组上的搜索、求和两数之和、盛水容器、三数之和

判断是否能用双指针的关键:数据是否有序或者问题是否满足单调性。如果移动一个指针能让结果朝着某个确定方向变化,双指针大概率可行。

5. 练习建议

刚接触双指针不要急着刷难题,先把上面几道经典题手动模拟一遍,画出每一步指针的位置变化。等你对指针移动的感觉建立起来之后,再去做变体题就会顺畅很多。

推荐的练习顺序:

  1. 有序数组去重(LeetCode 26)

  2. 两数之和 - 有序数组(LeetCode 167)

  3. 盛最多水的容器(LeetCode 11)

  4. 三数之和(LeetCode 15)——左右指针的进阶应用

下一节我们会学习链表反转,同样是面试高频考点。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 12:30:25

CANN/hcomm组调用结束接口

HcclGroupEnd 【免费下载链接】hcomm HCOMM&#xff08;Huawei Communication&#xff09;是HCCL的通信基础库&#xff0c;提供通信域以及通信资源的管理能力。 项目地址: https://gitcode.com/cann/hcomm 产品支持情况 Ascend 950PR/Ascend 950DT&#xff1a;不支持At…

作者头像 李华
网站建设 2026/5/9 12:26:11

CANN/ops-math复制填充反向算子

aclnnReplicationPad2dBackward 【免费下载链接】ops-math 本项目是CANN提供的数学类基础计算算子库&#xff0c;实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-math &#x1f4c4; 查看源码 产品支持情况 产品是否支持Ascend 950PR/Ascend 950D…

作者头像 李华
网站建设 2026/5/9 12:25:38

收藏 | 产品经理必修课:从入门到精通 Agent 架构,抢占 AI 产品先机!

文章探讨了 AI Agent 对产品逻辑的颠覆性影响&#xff0c;强调产品经理需从传统工具设计者转变为 Agent 架构师。文章介绍了 Agent 的四大核心模块&#xff1a;规划模块、记忆模块、行动模块和工具模块&#xff0c;并以市场分析报告为例说明其协作方式。此外&#xff0c;文章还…

作者头像 李华
网站建设 2026/5/9 12:21:59

构建基于Python与机器学习的智能客服

在人工智能技术落地的众多场景中&#xff0c;智能客服无疑是商业化最成熟、应用最广泛的领域之一。它不仅能够大幅降低企业的人力成本&#xff0c;还能通过7x24小时不间断服务提升用户体验。本文将围绕“Customer智能客服系统”这一主题&#xff0c;结合具体的Demo实现&#xf…

作者头像 李华