![]()
去年某大厂一面,面试官出了道"两数之和"的变形题。候选人写了段双重循环,面试官没说话,只是敲了敲屏幕上的时间复杂度。候选人当场愣住——他完全没意识到,题目里藏着一个免费提示。
这就是双指针(Two Pointers)模式的杀伤力。它不靠死记硬背,而是让你看见别人看不见的结构。今天这篇,我们把这套模式的两个变体拆干净。
变体一:对撞指针——从两头往中间夹
题目很经典:有序数组里找两个数,和等于目标值。暴力解法是嵌套循环,时间复杂度O(n²)。LeetCode会直接甩给你"Time Limit Exceeded"。
但题目说了"有序"。这两个字值千金。
对撞指针的精髓:一个指针站队首,一个站队尾,根据当前和的大小决定谁往中间移动。
和太大了?说明右边的数太肥,右指针左移。和太小了?左边的数太瘦,左指针右移。每次迭代排除一批不可能的组合,最终O(n)搞定。
![]()
代码结构长这样:
```python left, right = 0, len(nums) - 1 while left < right: current = nums[left] + nums[right] if current == target: return [left+1, right+1] elif current > target: right -= 1 else: left += 1 ```
没有魔法,就是利用了有序性这个隐藏条件。很多人面试时卡壳,不是因为算法难,是没养成"读题找提示"的肌肉记忆。
变体二:快慢指针——同向而行的侦探游戏
第二类场景更隐蔽:两个指针从同一侧出发,但速度不同。快指针探路,慢指针守门,或者两者保持固定间隔扫描。
典型应用包括:删除排序数组中的重复项、判断链表是否有环、找到倒数第K个节点。
快慢指针的核心逻辑:快指针负责遍历和发现,慢指针负责标记有效边界。
![]()
以"删除重复项"为例。快指针一路向前,遇到新元素就告诉慢指针:"这里该写了",然后慢指针前进一步。最终慢指针的位置就是去重后的数组长度。
两种变体的选择标准很清晰:数据有序且需要"配对"或"收缩范围"→对撞指针;需要"过滤"或"追踪相对位置"→快慢指针。
为什么面试官爱考这个?
双指针不是最难的算法,但它同时考察三件事:能不能从题目条件中提取隐藏信息(有序性)、能不能把O(n²)优化到O(n)、代码能不能写得干净无bug。
某头部厂面试官跟我聊过:「我见过太多候选人,明明会写对撞指针,但面试时就是想不到用。他们不是不会,是没形成模式识别的条件反射。」
这话很扎心,也很真实。刷题和面试之间,隔着一层"看见即会用"的熟练度。
双指针的代码量通常不超过10行,但每一行都有讲究。边界条件(left < right还是left <= right)、返回值要不要+1(1-indexed vs 0-indexed)、指针移动时机,都是埋雷点。
建议拿LeetCode 167(两数之和 II)、26(删除有序数组重复项)、142(环形链表 II)练手。这三道覆盖了双指针的90%面试场景。
你最近一次面试,有没有遇到过"明明会但当场没想起来"的算法题?后来复盘时,那个提示条件藏在哪句话里?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.