题目一:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)的时间内删除该节点
解法:O(1)的时间删除单向链表中的一个节点,题目关键在于它给了你一个节点指针,而且这个节点指针指向的 节点就是需要删除的那个节点。基于这个理解,我们就可以在O(1)的时间内删除,假设待删除的节点为i,i的下一个节点为j,我们可以将j的内容复制到i然后将 i->next = j->next即可实现删除,同时要考虑待删除节点是头节点或者是尾节点的特殊状况。
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution
{
void DeleteNode(ListNode** pListHead, ListNode *pToBeDeleted)
{
if (!pListHead || !pToBeDeleted)
return;
if (pToBeDeleted->next != nullptr)//既不是头节点也不是尾节点
{
ListNode *pNext = pToBeDeleted->next;
pToBeDeleted->val = pNext->val;
pToBeDeleted->next = pNext->next;
delete pNext;
pNext = nullptr;
}
else if (*pListHead == pToBeDeleted)//头节点
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
pListHead = nullptr;
}
else//尾节点
{
ListNode *pNode = *pListHead;
while (pNode->next != pToBeDeleted)
{
pNode = pNode->next;
}
pNode->next = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
};
题目二:在一个排序的链表中,如何删除重复的节点?例如1->2->3->3->5 删除后:1->2->5
解法:要注意设定一个指针保存待删除节点前一个节点的位置,以便将整个链表串联起来
#include <iostream>
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == nullptr )
return nullptr;
ListNode *pPreNode = nullptr;//若出现重复,保存的是重复的节点前一个节点的位置
ListNode *pNode = pHead;
while (pNode != nullptr)
{
ListNode * pNext = pNode->next;
bool needDel = false;
if (pNext != nullptr &&pNode->val == pNext->val) //判断是否重复出现
needDel = true;
if (!needDel)//木有重复
{
pPreNode = pNode;
pNode = pNode->next;
}
else
{
int value = pNode->val; //保存判断重复值
ListNode *pTobeDel = pNode;
while (pTobeDel != nullptr && value == pTobeDel->val) //符合条件 删除
{
pNext = pTobeDel->next;
delete pTobeDel;
pTobeDel = nullptr;
pTobeDel = pNext;
}
if (pPreNode == nullptr) //头节点就重复
pHead = pNext;
else
pPreNode->next = pNext;
pNode = pNext;//删除成功 下一个
}
}
}
};