LeetCode - 237. Delete Node in a Linked List
在 LeetCode 的众多算法题目中,第 237 题 “Delete Node in a Linked List”(在链表中删除节点)显得有些与众不同,甚至让不少初次接触的同学直呼 “太坑”。这道题的特别之处在于,它并非像常规链表删除操作那样,给定链表头节点和要删除节点的位置,而是直接将需要删除的节点作为输入,并且要求不返回任何内容,直接在原节点上进行修改。接下来,我们就深入剖析这道题目的解题思路,并通过 JavaScript 和 Python 两种语言实现解决方案。
1. 问题深度解析
题目仅提供了需要删除的节点本身,没有链表头节点等其他信息,这意味着我们无法像常规做法那样,通过遍历链表找到待删除节点的前一个节点,再修改其指针来完成删除操作。面对这种情况,我们必须转换思维,寻找新的突破口。
2. 解题思路探秘
解决这道题的核心技巧在于 “偷梁换柱”。既然无法直接删除当前节点,我们可以将下一个节点的值覆盖到当前节点上,然后将当前节点的指针指向 “下下个节点”,这样从链表的整体结构来看,就相当于删除了原本的当前节点。
举个例子,假设有链表 A -> B -> C -> D,现在要删除节点 B。我们将节点 C 的值赋给节点 B,此时链表变为 A -> C -> C -> D,接着让节点 B 的指针指向节点 D,最终链表就变成了 A -> C -> D,成功实现了 “删除” 节点 B 的效果。
3. 代码实现详解
3.1 JavaScript 实现
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} node
* @return {void} Do not return anything, modify node in-place instead.
*/
var deleteNode = function (node) {
node.val = node.next.val;
node.next = node.next.next;
};
在这段 JavaScript 代码中,deleteNode 函数接收需要删除的节点 node。第一行 node.val = node.next.val; 将下一个节点的值赋给当前节点,完成值的替换;第二行 node.next = node.next.next; 则让当前节点跳过下一个节点,直接指向 “下下个节点”,从而达到删除当前节点(逻辑上)的目的。
3.2 Python 实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
Python 代码的逻辑与 JavaScript 一致。在 Solution 类的 deleteNode 方法中,同样是先将下一个节点的值覆盖到当前节点,再调整指针指向,实现对给定节点的 “删除” 操作。
4. 总结与思考
LeetCode 237 题通过独特的输入方式,打破了我们对链表删除操作的常规认知,考查了我们灵活运用数据结构特性解决问题的能力。这种 “偷梁换柱” 的解题思路,不仅在本题中奏效,在其他涉及链表、数组等数据结构的变形题目中,也可能成为破题的关键。
通过本题的学习,我们更加深刻地认识到,在面对算法问题时,不能局限于固有思维模式,要敢于突破常规,从不同角度分析问题,才能找到巧妙的解决方案。希望本文的讲解能帮助大家理解这道题目,并在今后的算法学习中举一反三,攻克更多难题!