删除链表中的重复节点

一、题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。还有一种情况是1->1->1->1,那么返回的应该是null。

思路

因为链表是排序后的,所以重复的结点都是相邻的。为了避免出现头结点是重复的情况,我们可以定义一个新的头结点,指向旧的头结点,它的值为旧的头结点的值减1。这样头结点肯定不是重复的,返回的时候只需要返回新的头结点的next就行了。其次还需要定义一个pre指向新的头结点,p指向旧的头结点。然后依次遍历链表,查找与结点p的值重复的结点并删除。

二、代码实现

public ListNode deleteDuplication(ListNode pHead)
    {
        if(pHead == null || pHead.next == null) return pHead;
        ListNode newHead = new ListNode(pHead.val - 1); //新的头结点
        newHead.next = pHead;
        ListNode pre = newHead;
        ListNode p = pHead;
        while(p != null) {
            //1、如果p.next的值和p的值相等,说明需要删除和p的值相同的结点,最终要保证pre.val和p.val是不相等的
            if(p.next != null && p.val == p.next.val) {
                while(p != null && p.next != null && pre.next.val == p.val) p = p.next;
                if(p == null) { //说明从pre.next开始,一直到尾部都是值相等的节点,则直接把pre的next指向null,跳出循环。
                    pre.next = null;
                    break;
                }
                else { //说明p还没到尾部,那么pre的值和当前p的值肯定不一样,则把pre的next指向p
                    pre.next = p;
                }
            }
            //2、说明p的值和p.next的值不等,又因为是排序链表,那么说明pre、p、p.next的值肯定都不同,
            //然后就可以把pre指向p,p指向p的next
            else {
                pre = p;
                p = p.next;
            }
        }
        return newHead.next;
    }

 

posted @ 2018-08-19 23:06  neu_张康  阅读(600)  评论(0编辑  收藏  举报