18 O(1)时间删除链表结点
题目
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
C++ 题解
在单向链表中删除一个结点,最常规的做法无疑是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。这种思路由于需要顺序查找,时间复杂度自然就是O(n)。

我们可以把下一个结点的内容复制到需要删除的结点上覆盖原有的内容,再把下一个结点删除,就相当于把当前需要删除的结点删除了。

两个特殊情况:
- 如果要删除的结点位于链表的尾部,那么它就没有下一个结点:
此时我们仍然从链表的头结点开始,顺序遍历得到该结点的前序结点,并完成删除操作,这仍然属于O(n)时间的操作。 - 如果链表中只有一个结点,而我们又要删除链表的头结点(也是尾结点):
此时我们在删除结点之后,还需要把链表的头结点设置为NULL。
//使用指针的指针可以返回修改后的指针头节点
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if (pListHead == nullptr || pToBeDeleted == nullptr)
return;
//要删除的节点不是尾结点
if (pToBeDeleted->m_pNext != nullptr)
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;
delete pNext;
pNext = nullptr;
}
// 被删除的节点是尾节点,并且被删除的节点是链表的头节点,那么它是一个单节点的链表
else if (*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
*pListHead = nullptr;
}
// 被删除的节点是尾节点,并且被删除的节点是不是链表的头节点,那么它是一个多节点链表的尾节点
else
{
ListNode * pNode = *pListHead;
while (pNode->m_pNext != pToBeDeleted)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
python题解
思路与C++ 题解一致:
class ListNode:
def __init__(self):
self.value = None
self.next_node = None
class Solution:
def delete_node(self,head_node,del_node):
"""
删除指定节点
"""
if not head_node or not del_node:
return None
#要删除的节点不是尾节点
if del_node.next_node:
del_next_node=del_node.next_node
del_node.value=del_next_node.value
del_node.next_node=del_next_node.next_node
del_next_node.value=None
del_next_node.next_node=None
#链表只要一个节点,删除头节点(也是尾节点)
elif del_node==head_node:
head_node=None
del_node = None
#链表中有多个节点,删除尾节点
else:
node=head_node
while node.next_node!=del_node:
node=node.next_node
node.next_node=None
del_node=None
return head_node

浙公网安备 33010602011771号