力扣(LeetCode)82. 删除排序链表中的重复元素 II(C语言)

一、环境说明

  1. 本文是 LeetCode 82题 : 删除排序链表中的重复元素 II,使用c语言实现。
  2. 双指针+哑结点+链表删除。
  3. 测试环境:Visual Studio 2019。

二、代码展示

//双指针, left right。
//设置哑结点,方便第一个元素的删除。
struct ListNode* deleteDuplicates(struct ListNode* head) {
    struct ListNode* dummyHead = (struct ListNode*)calloc(1, sizeof(struct ListNode));//声明哑结点
    dummyHead->next = head;
    struct ListNode* left = dummyHead;//左指针从哑结点出发。
    struct ListNode* right = head;//右指针从头结点出发。
    if (NULL == right || NULL == right->next) {//空链表和单元素链表,返回头结点即可
        return head;
    }
    right = right->next;//right领先left两个位置
    while (right) {//右指针非空
        int x = right->val;
        if (x == left->next->val) {//一旦删除结点,结点就不后移了。
            while (left->next&&left->next->val == x) {//left->next非空,right的val和right左一位的val相同
                struct ListNode* temp = left->next;//待删除结点
                left->next = right;//删除temp
                temp->next = NULL;//避免野指针
                free(temp);//释放被删除结点的空间
                if(!right){//right为空
                    continue;//避免执行下一步,否则异常。
                }
                right = right->next;
                continue;//检测新的left->next是否删除
            }
            continue;//在删除结点后,不能执行下一步,避免错过新的right。
        }
        left = left->next, right = right->next;//没有删除操作,左右指针右移一位。
    }
    return dummyHead->next;//哑结点目的,即是作为答案返回。
}

三、思路分析

  • 分析题意,删除所有重复元素,如 [ 1 , 1 ] [1,1] [1,1]删除后为 [ ] [ ] [],又如 [ 1 , 2 , 3 , 3 , 4 , 4 , 5 ] [1,2,3,3,4,4,5] [1,2,3,3,4,4,5],删除后为 [ 1 , 2 , 5 ] [1,2,5] [1,2,5]
  • 这种可能删除头结点的链表,我们通常使用一个哑结点 d u m m y H e a d dummyHead dummyHead指向头结点 h e a d head head,这样就不用判断头结点删除的特例条件了。
  • 这题还是有两个特例:
  1. 传入空结点。
  2. 传入单元素结点。
  • 上述特例不会有重复元素,直接返回头结点即可
  • 一开始,我们让 l e f t = d u m m y H e a d left=dummyHead left=dummyHead r i g h t = h e a d − > n e x t right=head->next right=head>next,此时 r i g h t right right领先 l e f t left left两个位置,在之后的遍历,遇到相同元素,就很方便删除 l e f t left left r i g h t right right之间的一个结点了。每次删除后,我们也保持 r i g h t right right l e f t left left的相对距离为 2 2 2
  • 删除完成后,我们返回 d u m m y H e a d − > n e x t dummyHead->next dummyHead>next,即为所求链表。

四、代码分析

  • 理解思路很重要!
  • 欢迎读者在评论区留言,作为日更博主,看到就会回复的。

五、AC

力扣(LeetCode)82. 删除排序链表中的重复元素 II(C语言)_第1张图片

六、复杂度分析

  1. 时间复杂度: O ( n ) O(n) O(n) , n n n是链表的长度,一次遍历链表的时间复杂度是 O ( n ) O(n) O(n)
  2. 空间复杂度: O ( 1 ) O(1) O(1),除若干变量使用的常量空间,没有额外使用线性空间。

你可能感兴趣的:(小白leetcode,链表,leetcode,c语言,双指针,算法)