链表------删除有序单链表中重复的节点

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表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;
    }
}
View Code

 

posted @ 2018-05-05 21:31  东风知我欲山行  阅读(1905)  评论(0编辑  收藏  举报