LeetCode 237. 删除链表中的节点
题目描述
有一个单链表的 head,我们想删除它其中的一个节点 node。
给你一个需要删除的节点 node。你将 无法访问 head。
链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
· 给定节点的值不应该存在于链表中。
· 链表中的节点数应该减少 1。
· node 前面的所有值顺序相同。
· node 后面的所有值顺序相同。
解题思路
由于无法访问 head,我们不能通过修改前驱节点的 next 指针来删除当前节点。
巧妙解法:把下一个节点的值复制到当前节点,然后删除下一个节点。
这样效果上等价于删除了当前节点(虽然内存地址没变,但值被覆盖了)。
图解
假设链表为 4 -> 5 -> 1 -> 9,要删除节点 5:
第一步:把 next 的值 (1) 复制到当前节点 4 -> 1 -> 1 -> 9 第二步:让当前节点跳过 next 4 -> 1 -> 9Java 实现
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */classSolution{publicvoiddeleteNode(ListNodenode){// 将下一个节点的值赋给当前节点node.val=node.next.val;// 跳过下一个节点node.next=node.next.next;}}复杂度分析
指标 复杂度
时间复杂度 O(1)
空间复杂度 O(1)
关键点说明
- 题目保证 node 不是最后一个节点,因此 node.next 一定不为 null,无需做空检查。
- 本质是"偷梁换柱":不真正删除 node 这个对象,而是让它的值和结构"看起来"像是被删除了。
- 局限性:这个方法要求 node 不能是尾节点。如果要删除的是尾节点,就必须从头遍历找到前驱节点,无法做到 O(1)。这也是本题为什么明确保证"节点不是链表中的最后一个节点"。