面试题18-2:删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
FRESH...
正确方法:
若链表为空或链表只有一个节点,可直接返回链表头结点
if (pHead == nullptr || pHead->next == nullptr) return pHead;
该链表无头结点或头指针,若首结点就是重复的节点,首结点会被删除,就有问题了,所以应该添加上头指针,指向首结点。
//创建头指针ListNode* head=new ListNode(-1); head->next = pHead;
最后为了防止首结点已删除,返回时应返回头指针下一个节点。
return head->next;在遍历过程中遇到重复的需要删除节点,用prep保存前半部分的链表,用p保存后半部分的链表。
ListNode* deleteNode=p; p = p->next; delete deleteNode; deleteNode=nullptr;
代码为:
ListNode* deleteDuplication(ListNode* pHead) { if (pHead == nullptr || pHead->next == nullptr) return pHead; //创建头指针 ListNode* head=new ListNode(-1); head->next = pHead; ListNode* p = pHead, * prep = head; while (p!=nullptr) { if (p != nullptr && p->next != nullptr && p->val == p->next->val) { int duplicateVal=p->val; while (p != nullptr && p->val == duplicateVal) { ListNode* deleteNode=p; p = p->next; delete deleteNode; deleteNode=nullptr; } prep->next = p; } else { prep = p; p = p->next; } } return head->next; }
LONG LONG AGO...
方法1:
设置三个指针,p为工作指针,prep为p的前驱,q为p的后继,用于寻找最后一个重复的节点。从头遍历整个链表,若当前节点p与下一个节点的值相同,那么它们就是重复的节点,用指针q继续遍历后面有没有更多相同的重复节点直至到最后一个重复节点,删除p--q这一段节点,继续如此;但要注意的是,若头结点重复需另外处理,得重新设置pHead指针。
class Solution { public: ListNode* deleteDuplication(ListNode* pHead) { if (pHead == nullptr) return nullptr; //定义三个指针p是工作指针,prep是p的前驱,q是p的后继,p--q范围内的为相同的即将被删除的节点 ListNode *p = pHead, *prep = nullptr,*q=nullptr; while (p!=nullptr) { q = p->next; //若p,q内容相同,则判断q后面是否仍有一样内容的节点,若有,q后移一直到最后的一个相同节点处 if (q != nullptr && p != nullptr && p->val == q->val) { while (q!=nullptr&&q->next!=nullptr&&q->next->val == p->val) { q = q->next; } //若是头结点重复,则重置头结点 if (p == pHead) { pHead = q->next; p = pHead; } //若非头结点,则删除p---q段节点即可 else { p = q->next; prep->next = p; } } else { prep = p; p = p->next; } } return pHead; } };
方法2:手动添加一个头结点,指向首元节点。如此就不用了对头结点进行特殊处理了。其他思路同上
代码:ListNode* deleteDuplication(ListNode* pHead) { if (pHead == nullptr) return nullptr; //创建头结点 ListNode* head = new ListNode(0); head->next = pHead; ListNode *p = head->next, *q = nullptr, *prep = head; while (p != nullptr) { q = p->next; //若p与后继指针q所指相同,则继续向后寻找是否有更多重复的节点 if (p!= nullptr && q != nullptr && p->val == q->val) { while (q->next != nullptr && q != nullptr && q->next->val == p->val) { q = q->next; } p = q->next; prep->next = p; } else { prep = p; p = p->next; } } return head->next; }