题目:给定单向链表的头指针和一个结点指针,定义一个函数在o(1)时间删除该结点。链表结点与函数的定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pnext;
};
一般的思路肯定是定义两个指针,一前一后,当找到要删除的结点时,后面的指针再往后走一个,
然后再将前面的指针指向后面的指针,如下实现
void DeleteNode(ListNode** pplistHead, ListNode* pToBeDelete)
{
if (*pplistHead == nullptr && pToBeDelete == nullptr)
return;
ListNode* prev = nullptr;
ListNode* cur = *pplistHead;
bool flag = false;
while (cur->m_pnext != nullptr)
{
if (cur->m_pnext == pToBeDelete)
{
flag = true;
break;
}
prev = cur;
cur = cur->m_pnext;
}
if (flag == false)
return;
cur = cur->m_pnext;
prev->m_pnext = cur;
return;
}
但是时间复杂度是o(n),显然不符合题意。
在数组中我们知道,可以用覆盖的方式去删除元素,在这里可以借鉴这个思路,使用覆盖的方式,
void DeleteNode(ListNode** pplistHead, ListNode* pToBeDelete)
{
if (*pplistHead == nullptr && pToBeDelete == nullptr)
return;
if (pToBeDelete->m_pnext != nullptr)
{
ListNode* pNext = pToBeDelete->m_pnext;
pToBeDelete->m_nValue = pNext->m_nValue;
pToBeDelete->m_pnext = pNext->m_pnext;
delete pNext;
pNext = nullptr;
}
else if(pToBeDelete->m_pnext == nullptr)
{
delete pToBeDelete;
pToBeDelete = nullptr;
*pplistHead = nullptr;
}
else
{
ListNode* pNode = *pplistHead;
while (pNode->m_pnext != pToBeDelete)
{
pNode = pNode->m_pnext;
}
pNode->m_pnext = nullptr;
delete pToBeDelete;
pToBeDelete = nullptr;
}
}