LeetCode82 删除排序链表中的重复元素

Posted 小李一米九

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode82 删除排序链表中的重复元素相关的知识,希望对你有一定的参考价值。

Question

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

方法一 当然是递归大法

  • 当head后面有值并且和head的值相等,则一直找到与head不相等为止,然后对后面一个结点去递归,这样就删除了前面重复的结点
  • 当head后面有值且与head的值不相等时,那么就递归后面一个结点,跟在head后面
  • 最后返回head

思路还是很简单的,代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode 
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) 
 *     ListNode(int x) : val(x), next(nullptr) 
 *     ListNode(int x, ListNode *next) : val(x), next(next) 
 * ;
 */
class Solution 
public:
    ListNode* deleteDuplicates(ListNode* head) 
       //判断一下有没有下一个结点
        if (!head)
            return head;
        
        if (head->next && head->val == head->next->val)//如果有下一个结点且下一个结点相同
            while (head->next && head->val == head->next->val)//如果一直相同就一直循环
                head = head->next;
            
            return deleteDuplicates(head->next);//好了,遇到不同的了,返回进去(因为是删除所有相同的数,所以是从head->next开始)
        else //当不同时,赋值从下一个结点开始递归
            head->next = deleteDuplicates(head->next);//只要不同就接在后面
        
        return head;
    
;

方法二 学习了别人的做法

  • 定义一个dummy头结点,链接上原链表,cur指向原链表头部
  • ①当前结点value != 当前结点的下一结点value。那么让pre指针来到当前结点,这样就链接了前一结点和当前结点。然后当前结点移至下一结点
  • ②当前结点value == 当前结点的下一结点value。那么就让cur一直往下走直到当前结点value != 当前结点的下一结点value,然后此时是不能动pre指针的,要避免后面还有重复的,所以让pre->next = cur->next。然后当前结点移至下一结点。
  • 循环结束的条件结合子例即可。
/**
 * Definition for singly-linked list.
 * struct ListNode 
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) 
 *     ListNode(int x) : val(x), next(nullptr) 
 *     ListNode(int x, ListNode *next) : val(x), next(next) 
 * ;
 */
class Solution 
public:
    ListNode* deleteDuplicates(ListNode* head) 
        if (!head || !head->next) 
            return head;//如果头结点为空或者没有下一个值了
        

        ListNode* dummy = new ListNode(-1);
        dummy->next = head;//定义了一个头结点dummy

        //两个指针都从头开始
        ListNode* pre = dummy;
        ListNode* cur = head;
        while (cur && cur->next) //cur一直往下走
            if (cur->val == cur->next->val) //如果cur遇到的当前结点等于下一结点
                while(cur->next && cur->val == cur->next->val) 
                    cur = cur->next;//遍历所有这些相同的结点直到不相等
                
                pre->next = cur->next;//将下一结点的值赋给pre当前结点的下一个值
                cur = cur->next;//当前结点移至下一结点
            else//如果cur遇到的当前结点不等于下一结点,直接让pre来到当前结点,当前结点移至下一结点
                pre = cur;
                cur = cur->next;
            
        
        return dummy->next;
    
;

大概流程图

总结:相当于一开始cur就是要遍历所有结点的,最后通过返回dummy来确定答案,那么方法二的关键也就是pre的位置,cur每找到一个与下一个结点相同的结点先不能将pre调过去,避免后面还有重复的,当cur找到一个与下下一个结点不相同的结点(或下一结点为NULL)时,再把pre调过去,这样就可以直接跳过所有相同的值了!

以上是关于LeetCode82 删除排序链表中的重复元素的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode82 删除排序链表中的重复元素

迭代LeetCode 82. 删除排序链表中的重复元素 II

LeetCode 82 删除排序链表中的重复元素II

leetcode(82)---删除排序链表中的重复元素(双指针)

LeetCode 82. 删除排序链表中的重复元素 II

LeetCode 82. 删除排序链表中的重复元素 II