标签: 链表
难度: Easy
若链表中的某个节点,既不是链表头节点,也不是链表尾节点,则称其为该链表的「中间节点」。
假定已知链表的某一个中间节点,请实现一种算法,将该节点从链表中删除。
例如,传入节点 c
(位于单向链表 a->b->c->d->e->f
中),将其删除后,剩余链表为 a->b->d->e->f
示例:
输入:节点 5 (位于单向链表 4->5->1->9 中) 输出:不返回任何数据,从链表中删除传入的节点 5,使链表变为 4->1->9
标签: 链表
难度: Easy
若链表中的某个节点,既不是链表头节点,也不是链表尾节点,则称其为该链表的「中间节点」。
假定已知链表的某一个中间节点,请实现一种算法,将该节点从链表中删除。
例如,传入节点 c
(位于单向链表 a->b->c->d->e->f
中),将其删除后,剩余链表为 a->b->d->e->f
示例:
输入:节点 5 (位于单向链表 4->5->1->9 中) 输出:不返回任何数据,从链表中删除传入的节点 5,使链表变为 4->1->9
运行时间: 48 ms
内存: 14.8 MB
# 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
该题解的核心思路是通过复制节点的方式实现删除操作。具体做法是将待删除节点的下一个节点的值复制到当前节点,然后将当前节点的next指针指向下下个节点,这样就相当于删除了原节点的下一个节点,间接达到了删除当前节点的效果。由于直接修改了链表结构,因此无需返回任何值。
时间复杂度: O(1)
空间复杂度: O(1)
# 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. 删除指定节点,通过将下一节点的值复制到当前节点,并将当前节点的next指针指向下下个节点,实现删除。 """ node.val = node.next.val # 将下一节点的值复制到当前节点 node.next = node.next.next # 跳过下一节点,实现删除效果
如果待删除节点是链表中的倒数第二个节点,其`next.next`将是`None`,因为`next`指向的是最后一个节点,而最后一个节点的`next`是`None`。在这种情况下,可以正常复制倒数第一个节点的值到倒数第二个节点,并将倒数第二个节点的`next`设置为`None`,从而删除倒数第一个节点。
该算法并没有直接考虑待删除节点为链表尾节点的情况。由于算法依赖于节点后续的存在(至少需要一个后续节点来复制其值),因此如果`node.next`为`None`(即节点为尾节点),则无法执行此删除方法。这种方法仅适用于非尾部节点。
这种删除方法假设待删除的节点不是头节点,因为它依赖于节点的前驱节点(即至少存在一个节点在待删除节点之前)。在这种方法中,没有直接访问或修改前驱节点,而是通过修改当前节点的值和指针来实现删除效果。因此,这种方法不适用于头节点,因为头节点没有前驱节点。
删除操作通过修改值和指针来'伪删除'节点,实际上并没有从内存中移除节点。如果其他变量或数据结构引用了被删除的节点,它们将看到值被修改后的状态。例如,如果有一个变量引用了被'删除'的节点,那么该变量现在将引用一个值被改变且`next`指针被重定向的节点。这可能导致不一致和意外的行为,特别是在并发环境中。