You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode 203移除链表元素:curr指针未更新head的问题求助

链表移除元素问题:curr指针与head指针的更新逻辑解析

为什么curr更新后head没变化?

Java里的对象引用是值传递,你定义的curr = head,本质是把head指向的链表节点地址复制给了curr变量。此时curr和head是两个独立变量,只是初始指向同一个节点。当你在第一个循环里执行curr = curr.next,只是改变了curr自己的指向,完全不会影响head变量的指向。

比如测试用例[7,7,7,7],第一个循环结束后curr会变成null,但head仍然指向原来的第一个7节点,所以最后返回head自然还是原链表,和预期的空链表不符。

你的代码问题分析

  1. 头部节点处理不彻底:第一个循环只更新了curr,没同步更新head,导致原head指针还停留在要删除的节点上。
  2. 第二个循环逻辑有漏洞:就算curr.next是要删除的节点,你还是会执行curr = curr.next,这会导致跳过后续节点的检查。比如遇到连续两个要删除的节点时,第二个会被漏掉。

修正方案

方案1:直接更新head指针

先单独处理头部所有需要删除的节点,把head直接移动到第一个不需要删除的节点,再用curr处理后续节点:

public ListNode removeElements(ListNode head, int val) {
    // 跳过头部所有等于val的节点
    while (head != null && head.val == val) {
        head = head.next;
    }
    // 如果处理完头部已是空链表,直接返回
    if (head == null) {
        return null;
    }
    ListNode curr = head;
    // 处理中间和尾部的节点
    while (curr.next != null) {
        if (curr.next.val == val) {
            // 删除curr.next节点
            curr.next = curr.next.next;
        } else {
            // 只有当前节点的下一个不用删除时,才移动curr
            curr = curr.next;
        }
    }
    return head;
}

方案2:使用dummy哑节点(更简洁通用)

哑节点是处理链表头可能被删除场景的常用技巧,它的next指向原head,这样不用单独处理头部,统一遍历逻辑:

public ListNode removeElements(ListNode head, int val) {
    ListNode dummy = new ListNode(-1);
    dummy.next = head;
    ListNode curr = dummy;
    while (curr.next != null) {
        if (curr.next.val == val) {
            curr.next = curr.next.next;
        } else {
            curr = curr.next;
        }
    }
    // 哑节点的next就是新的链表头
    return dummy.next;
}

这个方案里,不管原head是不是要被删除,最后返回的dummy.next都会是正确的新头部,包括空链表的情况。

内容的提问来源于stack exchange,提问作者coder2312

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:20:24