题目一:在O(1)时间内删除链表的节点
给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点
思路:
常规的思路是从头到尾去遍历链表,找到要删除的节点。但是这里对时间复杂度的要求是O(1)。换个角度,其实删除一个节点可以将它后继节点的数据覆盖该节点,然后删掉后继的节点就可以了。但是要考虑,被删除的节点是是否是尾节点,如果是尾节点还要考虑,这时链表中如果只有一个节点的情况。这是十分要注意的。
代码 :
struct ListNode
{
int m_nvalue;
ListNode* m_pNext;
};
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if (!pListHead || !pToBeDeleted)
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)
{
*pListHead == nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
//链表中有多个节点删除尾节点
else {
ListNode* pNext = *pListHead;
while (pNext->m_pNext!=pToBeDeleted)
{
pNext = pNext->m_pNext;
}
pNext->m_pNext = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
题目二:删除链表中的重复节点
在一个排序链表中,如何删除重复的节点。
如上图所示, 如果节点3和4是重复节点,就将节点2和5相连。
思路:
这道题的思路还是比较朴实,就是从头节点开始遍历链表,并且记录当前节点和当前节点的前驱节点。当前节点和后继节点的值相同时,表示这两个节点为重复节点,需要删除,并且将当前节点更新为被删除节点的后继节点,如果依然为重复节点则继续删除,直到不为重复节点为止。这个时候还要判断如果前驱节点为空,即头节点为重复节点并且被删除后,需要把头节点更新为当前节点。如果前驱节点不为空,那么就把前驱节点的下一个节点指向当前节点。一定要考虑周全边界情况,比如头节点和尾节点,还有考虑前驱和后继节点的时候也要考虑是否为nullptr的情况。
代码:
struct ListNode {
int m_nValue;
ListNode* m_pNext;
};
void DeleteDuplication(ListNode**pHead)
{
if (pHead == nullptr || *pHead == nullptr)
return;
ListNode*pPreNode = nullptr;
ListNode* pNode = *pHead;
while (pNode!=nullptr)
{
ListNode*pNext = pNode->m_pNext;
bool needDelete = false;
if (pNext != nullptr&&pNext->m_nValue == pNode->m_nValue)
needDelete = true;
if (!needDelete)
{
pPreNode = pNode;
pNode = pNode->m_pNext;
}
else {
int value = pNode->m_nValue;
ListNode* pToBeDel = pNode;
while (pToBeDel!=nullptr&&pToBeDel->m_nValue==value)
{
pNext = pToBeDel->m_pNext;
delete pToBeDel;
pToBeDel = nullptr;
pToBeDel = pNext;
}
if (pPreNode = nullptr)
*pHead = pNext;
else
pPreNode->m_pNext = pNext;
pNode = pNext;
}
}
}
复习:
其实过程不复杂,但是代码写起来有点绕,过程要理清楚。
二刷代码:
struct ListNode
{
int m_nvalue;
ListNode* m_pNext;
};
void DeleteDuplication(ListNode** pHead)
{
if (pHead == nullptr || *pHead == nullptr)
return;
ListNode* pNode = *pHead;
ListNode* preNode = nullptr;
while (pNode!=nullptr)
{
ListNode* pNext = pNode->m_pNext;
bool needDelete = false;
if (pNode->m_nvalue == pNext->m_nvalue && pNext != nullptr)
{
needDelete = true;
}
if (!needDelete)
{
pNode = pNode->m_pNext;
preNode = pNode;
}
else
{
int value = pNode->m_nvalue;
ListNode* pDelete = pNode;
while (pDelete->m_nvalue==value&&pDelete!=nullptr)
{
pNext = pDelete->m_pNext;
delete pDelete;
pDelete = nullptr;
pDelete = pNext;
}
if (preNode == nullptr)
*pHead = pNext;
else
{
preNode->m_pNext = pNext;
}
pNode = pNext;
}
}
}