【算法--链表】82.删除排序链表中的重复元素 II--通俗讲解

发布于:2025-09-07 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、题目是啥?一句话说清

给你一个已经排序的链表,删除所有重复数字的节点(包括本身),只留下不同的数字,并返回处理后的链表。

示例:

  • 输入:1 → 1 → 2 → 3 → 3
  • 输出:2(因为所有1和3都被删除,只留下2)

二、解题核心

使用虚拟头节点简化操作,遍历链表,对于每个节点,检查其后是否有重复节点,如果有则跳过整个重复序列。 这就像处理一排已经排序的队伍,如果发现连续多个人身高相同,就让所有这些人都离开队伍。

三、关键在哪里?(3个核心点)

想理解并解决这道题,必须抓住以下三个关键点:

1. 虚拟头节点(Dummy Node)的使用

  • 是什么:在原始链表前添加一个不存储实际数据的节点。
  • 为什么重要:因为头节点可能被删除(如示例中头节点1被删除),使用虚拟头节点可以避免单独处理头节点变化的情况。

2. 跳过整个重复序列

  • 是什么:当发现重复时,不是只跳过下一个节点,而是找到重复序列的结束位置,然后一次性跳过所有重复节点。
  • 为什么重要:因为题目要求删除所有重复数字的节点,而不是保留一个。

3. 指针操作的安全性

  • 是什么:在遍历链表时,需要确保指针不为空,避免空指针异常。
  • 为什么重要:因为可能操作到链表的末尾,需要谨慎检查指针的next属性。

四、看图理解流程(通俗理解版本)

让我们用链表 1 → 1 → 2 → 3 → 3 的例子来可视化过程:

  1. 初始化

    • 创建虚拟头节点 dummy,其 next 指向头节点 1。
    • 设置当前指针 curr 指向 dummy
    • 初始状态:dummy → 1 → 1 → 2 → 3 → 3
  2. 第一轮检查

    • curr 指向 dummy,检查 curr.next (1) 和 curr.next.next (1) 的值是否相等。
    • 相等,说明有重复,需要删除所有值为1的节点。
    • 找到第一个值不为1的节点(节点2)。
    • curr.next 指向节点2(跳过所有1)。
    • 链表状态:dummy → 2 → 3 → 3
    • curr 仍然指向 dummy(因为可能新的开头还有重复)。
  3. 第二轮检查

    • curr 指向 dummy,检查 curr.next (2) 和 curr.next.next (3) 的值是否相等。
    • 不相等,说明没有重复,移动 currcurr.next(指向2)。
    • 链表状态:dummy → 2 → 3 → 3
  4. 第三轮检查

    • curr 指向2,检查 curr.next (3) 和 curr.next.next (3) 的值是否相等。
    • 相等,说明有重复,需要删除所有值为3的节点。
    • 找到第一个值不为3的节点(null)。
    • curr.next 指向 null(跳过所有3)。
    • 链表状态:dummy → 2
  5. 结束

    • 返回 dummy.next,即节点2。

五、C++ 代码实现(附详细注释)

#include <iostream>
using namespace std;

// 链表节点定义
struct ListNode {
   
   
    int v

网站公告

今日签到

点亮在社区的每一天
去签到