C++ LeetCode 237. 删除链表节点(仅给定节点)
在单向链表中,常规删除操作通常需要前驱节点。LeetCode 237 题的特殊性在于无法直接获取前驱。本文介绍一种巧妙的替代方案:通过覆盖当前节点值为后继节点的值,并删除后继节点,从而在不破坏链表结构的前提下完成删除任务。
问题背景与核心难点
题目要求实现一个函数,删除单向链表中的一个节点(非尾节点)。通常的删除操作需要知道待删节点的前一个节点,通过修改前驱节点的 next 指针来绕过待删节点。
然而,在本题中,我们只能访问到要删除的那个节点 node,无法拿到它的 prev。这打破了常规思维:
- 限制条件:仅传入一个节点指针,不能获取头结点或前驱节点。
- 目标:从逻辑上将当前节点从链表中移除,使链表结构连续。
解决方案:值覆盖技巧
虽然我们无法改变“当前节点”本身,但我们可以改变它的内容。算法的核心思想是将下一个节点的值移动到当前节点,然后执行常规的“删除下一个节点”的操作。
第 1 步:替换当前节点的数值
目的:让当前节点表现得像是“下一个节点”,以便后续删除后继节点时,当前节点能正确跳过它。
操作:读取下一个节点的数据域,赋值给当前节点。node->val = node->next->val;
第 2 步:重新连接指针
目的:更新 current 的 next 指针,使其指向下下个节点,从而在物理上断开与“旧下一节点”的连接。
操作:node->next = node->next->next;
第 3 步:释放内存
目的:防止内存泄漏。由于我们在第二步中已断开了指针引用,被跳过的旧下一节点需要通过 delete 手动释放空间。
操作:使用 C++ 标准的 delete 关键字清理临时节点。
C++ 完整代码实现
class Solution {
public:
void deleteNode(ListNode* node) {
// 记录要删除的下一个节点
ListNode *tmp = node->next;
// 将下一个节点的值复制到当前节点
node->val = node->next->val;
// 跳过下一个节点,直接连到下下个节点
node->next = tmp->next;
// 释放被跳过的节点内存,防止内存泄漏
delete tmp;
}
};
关键要点总结
本解法成功避开了寻找前驱节点的难题,将删除操作的复杂度降至最优。以下是需要注意的细节:
- 边界检查:题目明确指出给定节点不是尾节点,因此
node->next永远有效,无需做空指针判断。 - 内存管理:C++ 开发者必须特别注意
delete的使用,否则会导致内存泄漏;而在 Java 等具有垃圾回收机制的语言中,这一步可省略,直接node.next = node.next.next即可。 - 时间/空间复杂度:该算法只需遍历一次,时间复杂度为 O(1);不额外开辟空间,空间复杂度同样为 O(1)。
以上就是 LeetCode 237. 删除链表的节点的详细内容,更多关于 LeetCode 链表题目的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













