1. 问题理解与需求分析
链表去重问题在算法面试和实际工程中都很常见。这道题的特别之处在于它要求删除所有重复出现的元素,而不仅仅是保留一个副本。换句话说,如果一个元素在链表中出现多次,那么所有该元素的节点都需要被移除。
举个例子,对于链表 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5,常规的去重操作会保留一个3和一个4,结果为 1 -> 2 -> 3 -> 4 -> 5。但本题要求的结果是 1 -> 2 -> 5,因为3和4都重复出现了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路与算法设计
2.1 虚拟头节点技巧
处理链表问题时,使用虚拟头节点(dummy node)是一个常用技巧。这可以简化对头节点的特殊处理,因为头节点可能被删除。我们创建一个值为0的虚拟节点,其next指向真正的头节点。
java复制ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
2.2 双指针遍历策略
我们需要两个指针:
cur指针:指向当前处理的节点的前一个节点next指针:用于检查后续节点是否有重复
核心逻辑是:
- 比较
cur.next和cur.next.next的值 - 如果相同,记录这个值,然后跳过所有等于该值的节点
- 如果不同,移动
cur指针到下一个节点
2.3 边界条件处理
需要考虑的特殊情况包括:
- 空链表
- 单节点链表
- 所有节点值都相同
- 重复节点在链表末尾
3. 代码实现详解
让我们逐行分析提供的Java解决方案:
java复制class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode cur = dummyHead;
while (cur.next != null && cur.next.next != null) {
int val1 = cur.next.val;
if (cur.next.val == cur.next.next.val) {
while (cur.next != null && cur.next.val == val1) {
