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自然还是原链表,和预期的空链表不符。
你的代码问题分析
- 头部节点处理不彻底:第一个循环只更新了curr,没同步更新head,导致原head指针还停留在要删除的节点上。
- 第二个循环逻辑有漏洞:就算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
相关产品推荐
相关产品推荐

