删除链表中的重复元素

删除链表中重复元素Ⅰ(保留1个重复元素)

题目描述:

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

样例:

输入:head = [1,1,2]
输出:[1,2]

算法思路:

遍历链表,当前链表节点与下一个节点值相同,则删除下一个节点。

时间复杂度:

O(n)

代码实现:

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head)   return head;
        ListNode* p = head;
        // 遍历链表,如果下一个节点的值与当前节点值相同,则将下一个节点删除。
        while(p->next){
            if(p->val == p->next->val) p->next = p->next->next;
            else    p = p->next;
        }
        return head;
    }
};

删除链表重复元素 Ⅱ(不保留重复元素)

题目描述:

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。即将重复的元素全部删除。

样例:

输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

算法思路:

由于排好序的链表,相同值节点相邻,所以可以看当前节点后一段相同值节点个数,如果个数大于1,则将这一段全部删除,否则就保留这一段。由于可能会将头节点删除,所以建立一个虚拟头节点,防止头节点被删除的情况/

时间复杂度

遍历一遍链表,所以时间复杂度是O(n)

代码实现:

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;

        auto p = dummy;
        while(p->next){
            auto q = p->next;
            // 看p下一端相等元素的个数。遍历中q指向下一段相同元素下一个节点
            while(q && p->next->val == q->val)  q = q->next;
            // 如果下一段相同元素的个数等于1,保留这一段节点。
            if(p->next->next == q)  p = p->next;
            // 否则就将下一段相同值节点全部删除。
            else    p->next = q;
        }
        // 结果返回虚拟头节点下一个节点。
        return dummy->next;
    }
};

你可能感兴趣的:(leetcode题解,链表,数据结构,算法)