Remove Duplicates from Sorted List I II -- leetcode

(1) Remove Duplicates from Sorted List I
题目意思: 删除重复节点,但是保留第一个重复的结点.
For example,
Given 1->2->3->3->4->4->5, return 1->2->3->4->5.
Given 1->1->1->2->3, return 1->2->3.

思路:
(1) 定义两个指针,一个指向当前结点,一个指向其前驱
(2) 判断当前结点是否与其前驱结点值一样,一样则向后移动当前结点, 直到不在重复为止.
(3)此时当前结点可能为空, 删除重复结点后,前一个指针的next设为null即可;
(4)如果移动后,当前结点不为空,需要将前一个指针的next指向p(无论上一次p是否移动过, 没有移动即没有重复结点的情况下,前一个结点本来就是其前继结点,如果移动,那么p指向的正好是第一个不同于其前继的结点)
代码:

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == NULL) return NULL;
        ListNode *pre = head;//前驱结点
        ListNode *p = head -> next;
        while (p != NULL){
            while (p != NULL && pre -> val == p -> val){//前后结点值相同,移动p
                p = p -> next;
            }
            if (p == NULL) pre -> next = NULL;
            else {
                pre -> next = p;
                pre = p;
                p = p -> next;
            }

        }
        return head;
    }
};

2 Remove Duplicates from Sorted List II – leetcode
题目意思:删除重复节点,不保留任何重复结点.
For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.

思路:(与上一题不同,要求同时将重复的结点删除)
(1)首先给原链表定义一个不重复的头结点;
(2)定义两个指针,其中一个始终指向不重复的结点(初始化的时候指向我们定义头结点),一个指向当前结点
(3)依次比较当前结点与其后一个结点是否重复,重复则当前指针向后移动
(4)判断当前结点的指针是否是第一个指针的后继,
1)如果是,表示当前结点不重复,然后前一个和后一个指针依次向后移动一次.
2)如果不是,表示后一个指针指向的结点重复, 移动后, 后一个指针指向的正是重复结点的最后一个,因此将前一个指针(始终指向不重复结点的指针)的后继指向后一个指针的后继,然后让后一个指针成为新链表中前一个指针的后继

代码:

class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        //链表为空的情况
    if (pHead==NULL) return NULL;
        //定义一个不重复的头结点
        ListNode *newList = new ListNode(-1);
        newList -> next = pHead;
        //下面的情况头结点不重复
        ListNode *pre = newList;//前一个指针,始终指向链表中不重复的结点
        ListNode *p = pre-> next;

        while(p!=NULL){
            //p的下一个结点和p重复,则向后移动p
            while (p -> next != NULL && p -> next -> val == p -> val){ 
                p = p -> next;
            }
            //pre的后继结点不是p,证明p向后移动过,即有重复的结点,移动后的 p 指向的是重复结点的最后一位
            if (pre -> next != p){//有重复的情况
                pre -> next = p -> next;//将重复的所有结点删除
                p = pre -> next;
            }else {//没有重复的情况(两个指针同时向后移动一次)
                pre = p;
                p = p -> next;
            }
        }
        return newList->next;
    }
};
不积跬步,无以至千里;不积小流,无以成江海。
原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779781.html