83. Remove Duplicates from Sorted List

题目

Given a sorted linked list, delete all duplicates such that each element appears only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

删除链表中重复的元素,保证每个元素只出现一次。

解题思路

因为链表从小到大排序,当前元素的下一个元素只有两种可能:

  1. 与当前元素相同(即,当前元素在链表中重复出现)
  2. 大于当前元素(即,当前元素为链表中的唯一元素)

根据上面的观察,检查一个元素是否重复出现只需要和该元素的下一个元素进行比较即可。因此,我们需要两个指针。第一个指针p指向当前元素,第二个指针t永远指向p的下一个元素。

比较tp的值:

  1. tp不相等,那么意味着p为唯一元素。所以保留该元素,然后将指针p移动到下一个元素
  2. tp相等,那么意味着该元素重复出现。所以只保留一份该元素,删除重复元素t。然后p仍指向当前元素,移动t到下一个元素,继续与p进行比较,重复以上步骤,直到tp不相等

举个例子:

一个链表:1->1->1->1->3->4
从头循环该链表,一次循环中完成以下步骤:
1. p = 1, 
   t = p->next 所以 t = 1
2. t == p?
   比较t和p,因为t,p相等,所以删除t
   注意!删除t之前,我们要设置p->next = t->next,不然链表会断掉
   新的链表:1->1->1->3->4
3. 返回第一步...

因为t永远是p的下一个元素,只要t==p,那么重复的t都不会删除直到t=3

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        
        if(!head) {return NULL;}

        ListNode *p = head, *t;
        
        while(p != NULL) {
            t = p->next;
            if(t != NULL) {
                if(p->val == t->val) { // 当前元素与下一个元素相同
                    p->next = t->next; // p的下一个元素为t的下一个元素
                    delete t; //删除重复元素t
                }else { // 当前元素与下一个元素不同,移动指针到下一个元素
                    p = p->next;
                }
            }else { // 当前元素为列表中最后一个元素
                return head;
            }
        }
        
        return head;
    }
};

你可能感兴趣的