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