LeetCode删除链表倒数第N个节点:Java代码超时求助
删除链表倒数第N个节点代码超时问题排查
给定链表的头节点head,删除链表的倒数第n个节点并返回头节点。我写了这段Java代码,但运行时出现「Time limit exceeded(超时)」错误,请问原因是什么?
class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode ptr1=head, ptr2=head; for(int i =0;i<n;i++) ptr2=ptr2.next; while(ptr2.next!=null){ ptr1=ptr1.next; ptr1=ptr2.next; } ptr1.val = ptr1.next.val; ptr1.next = ptr1.next.next; return head; } }
超时原因
- 死循环导致超时:在
while循环里,你写错了指针移动逻辑——把ptr1赋值成ptr2.next,而没有移动ptr2。这会让ptr2一直停在原地,循环条件ptr2.next!=null永远满足,程序陷入死循环,自然会超时。 - 边界情况未处理:如果要删除的是链表的头节点(比如n等于链表总长度),
ptr2会变成null,此时访问ptr2.next会直接抛出空指针异常,而且原逻辑也没法处理这种场景。
修正后的代码
class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { // 虚拟头节点,统一删除逻辑,避免头节点删除的边界问题 ListNode dummy = new ListNode(0); dummy.next = head; ListNode ptr1 = dummy; ListNode ptr2 = dummy; // 让ptr2先往前走n步 for (int i = 0; i < n; i++) { ptr2 = ptr2.next; } // 两个指针一起走,直到ptr2走到链表末尾 while (ptr2.next != null) { ptr1 = ptr1.next; ptr2 = ptr2.next; } // 直接删除ptr1的下一个节点 ptr1.next = ptr1.next.next; return dummy.next; } }
关键修正点
- 加了虚拟头节点:不管要删除的是头节点还是中间节点,都能用同样的指针操作逻辑处理,不用单独判断。
- 修复循环内的指针移动:让
ptr1和ptr2同步前进,保证循环能正常结束,不会死循环。 - 去掉错误的节点值覆盖:原代码用覆盖值的方式模拟删除,逻辑不严谨(比如删除最后一个节点时会出错),直接修改指针指向才是链表删除节点的正确方式。
内容的提问来源于stack exchange,提问作者Nihal Pandey
相关产品推荐
相关产品推荐

