D
AI
学习工作台
8 周后端冲刺2026-05-222 分钟阅读

双指针技巧

对撞指针、快慢指针、去重与合并有序序列

8周冲刺week1双指针算法记笔记标记疑惑

为什么双指针能降复杂度

暴力枚举两个下标是 O(n²)。双指针利用 移动方向的单调性:每轮至少有一个指针只朝一个方向走,总移动次数 O(n),从而把平方级降为线性。

Week 1 的数组基础见 week01-array-basics;双指针常与排序、滑动窗口组合。站内 /chapters/algorithm-lab/problems 提供了可交互练习环境。

对撞指针(相向)

两个指针从两端向中间移动,经典于 有序数组两数之和

def two_sum_sorted(nums, target):
    i, j = 0, len(nums) - 1
    while i < j:
        s = nums[i] + nums[j]
        if s == target:
            return [i, j]
        elif s < target:
            i += 1
        else:
            j -= 1
    return []

盛最多水的容器:同样对撞,比较面积后移动较短边(短板决定高度,移长边不可能更大)。

三数之和:外层枚举第一个数并去重,内层对撞求两数之和为 -nums[i],注意跳过重复的 (i, left) 组合。

快慢指针(同向)

链表环检测(Floyd):快指针走 2 步、慢指针 1 步,相遇则有环;入环点再设一指针从头同步走,相遇处为环入口。

def has_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow is fast:
            return True
    return False

数组原地划分slow 维护「有效区」边界,fast 扫描。典型题:移除元素、移动零、荷兰国旗(三路划分)。

找重复数 / 环入点变体:将数组下标视为「next 指针」,等价链表环问题。

合并与去重

合并两个有序数组:双指针比较,小者写入结果;一方耗尽则拷贝剩余。

有序数组去重slow 指向下一个写入位置,fast 扫描,仅当 nums[fast] != nums[slow-1] 时写入。

def remove_duplicates(nums):
    if not nums:
        return 0
    slow = 1
    for fast in range(1, len(nums)):
        if nums[fast] != nums[fast - 1]:
            nums[slow] = nums[fast]
            slow += 1
    return slow

面试表达模板

  • 说明为何单调 → 双指针合法。
  • 写出循环不变量(例如:窗口外元素已处理)。
  • 边界:i < jfast 空指针、全重复数组返回 1。
  • week01-sliding-window 的区别:滑动窗口维护 连续区间 的统计量;双指针更宽,包含非连续的同向扫描。读题时先问「是否必须连续子数组/子串」。

    练习建议

    每天 2 题:1 道对撞 + 1 道快慢。错题记录「单调性来自哪里」,比记代码更有用。

    实战巩固与面试表达

    本篇属于 8 周冲刺 week01-two-pointers 主题。复习时先闭卷回答 frontmatter 中三张 flashcard,再展开口述两个「为什么」:为什么这种方案能 work、边界失败时如何降级。与相邻章节对照:算法篇强调复杂度与模板,Go 篇强调工程默认写法,中间件篇强调线上故障案例。

    动手与自检清单

    用 25 分钟限时做 1 道相关练习题或画出一张架构/数据结构示意图;用 5 分钟写 STAR 片段说明你在项目里是否用过类似技术。记录 3 个面试追问及你的标准答法,存入 /zh/notebook/master-plan 笔记。若某点不熟,回到对应 /chapters 交互 Lab 重新走一遍流程,比死记卡片更有效。

    易错点提醒

    避免只背名词不会画图;避免只说优点不谈 trade-off(性能、一致性、运维成本至少提一项);避免把学习 Demo 说成百万 QPS 生产。回答时使用「场景 → 方案 → 结果 → 反思」四段式,体现工程成熟度。

    知识卡片

    问题

    对撞指针适用的前提是什么?

    点击翻转查看答案

    答案

    通常要求序列有序或存在单调性:和小于目标只能增大左端,大于目标只能减小右端,每步排除一种可能,保证 O(n)。

    问题

    快慢指针在链表找中点的写法?

    点击翻转查看答案

    答案

    slow 每次 1 步,fast 每次 2 步;当 fast 到末尾时 slow 在中点。偶数长度时 slow 偏右一位,按题意调整。

    问题

    三数之和如何避免重复三元组?

    点击翻转查看答案

    答案

    数组排序后固定 nums[i],双指针扫 [i+1,n-1];找到后和若等于上一组相同 left 值则跳过 left++,同理处理 i 重复。