链表------删除有序单链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
第一种方法:递归 //耗时5ms
ListNode* deleteDuplication(ListNode* pHead) { if (pHead == nullptr || pHead->next == nullptr) { // 只有0个或1个结点,则返回 return pHead; } if (pHead->val == pHead->next->val) { // 当前结点是重复结点 ListNode *pNode = pHead->next; while (pNode != nullptr && pNode->val == pHead->val) { // 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点 pNode = pNode->next; } return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归 } else { // 当前结点不是重复结点 pHead->next = deleteDuplication(pHead->next); // 保留当前结点,从下一个结点开始递归 return pHead; } }
第二种方法:每次找一个不重复的元素,加入链表//耗时7ms
ListNode* deleteDuplication(ListNode* pHead)
{
// 解法2:每次找一个不重复的元素,加入链表
if (pHead == nullptr)
return pHead;
ListNode *newhead = new ListNode(1);
ListNode *index = newhead;
ListNode *p = pHead;
bool rept = false;
while (p != nullptr){
rept = false;
while (p->next != nullptr && p->val == p->next->val){
rept = true;
p = p->next;
}
if (rept == false){
index->next = new ListNode(p->val);
index = index->next;
p = p->next;
}
else{
if (p->next == nullptr){
break;
}
else{
p = p->next;
}
}
}
return newhead->next;
}
第三种方法:耗时3ms
ListNode* deleteDuplication(ListNode* pHead) { if(pHead==nullptr || pHead->next==nullptr) return pHead; ListNode *pre=NULL; ListNode *p=pHead; ListNode *q=p->next; while(p!=nullptr) { //当前结点p,(其实是p指向当前结点),与它下一个结点p->next的val相同,说明要删掉有这个val的所有结点 if(p->next!=NULL && p->next->val==p->val) { q=p->next; //找到q,它指向最后一个与p val相同的结点,那p 到 q (包含) 都是要删除的 while(q!=nullptr && q->next!=nullptr && q->next->val==q->val) q=q->next; //如果p指向链表中第一个元素,p -> ... -> q ->... , 要删除p到q, 将指向链表第一个元素的指针pHead指向q->next。 if(p==pHead) pHead=q->next; else pre->next=q->next; //如果p不指向链表中第一个元素,pre -> p ->...->q ->... ,要删除p到q,即pre->next = q->next //当前处理的p要向链表尾部移动 p=q->next; } else { pre=p; p=p->next; } } return pHead; }
第四种方法:java 使用HashMap记录每个节点是否重复出现,时间复杂度为O(N),空间复杂度为O(N)
public ListNode deleteDuplication(ListNode pHead) { // 解法1:使用hashMap记录个数 if(pHead==null) return pHead; HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>(); ListNode cur = pHead; while(cur != null){ if(map.containsKey(cur.val) == false){ map.put(cur.val, true); }else{ map.put(cur.val, false); } cur = cur.next; } Set<Integer> set = map.keySet(); boolean isfst = true; ListNode pre = pHead; for (int temp : set){ if (map.get(temp) == true){ if(isfst){ pHead.val = temp; isfst = false; } else{ pre.next.val = temp; pre = pre.next; } } } if(isfst) // 链表中只含有重复节点 return null; else // 链表含有不重复的节点 pre.next = null; return pHead; } }