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

[toc]

题目介绍

题解一

解题思路

  • 递归法

    首先通过遍历删除与头结点同值的结点,后面1部分的链表通过递归删除其中的重复结点,然后将当前头结点与后面1部分链表(已删除重复结点)连接起来,最终返回当前头结点。

  • 复杂度分析

    假设链表有n个结点,则时间复杂度和空间复杂度都为$O(n)$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head==nullptr)
return head;
ListNode* cur=head;
while(cur!=nullptr && cur->val == head->val)
cur = cur->next;
head->next = deleteDuplicates(cur);
return head;
}
};

题解二

解题思路

  • 递归法

    首先取出头结点,然后通过递归删除剩余链表中的重复结点并将其与头结点连接,然后判断当前头结点和第2个结点是否重复(如果重复则删除)。

  • 复杂度分析

    假设链表有n个结点,则时间复杂度和空间复杂度都为$O(n)$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head==nullptr)
return head;
head->next = deleteDuplicates(head->next);

if (head->next!=nullptr && head->val==head->next->val)
return head->next;
return head;
}
};

题解三

解题思路

  • 迭代法

    整体思路为用哨兵sentry保存当前最后1个不重复结点,当发现新的不重复结点时将哨兵与该结点连接(这样就是一次性删除多个重复结点)。

    具体方法为:遍历链表,当发现cursentry异值时则一次性删除多个重复结点并更新最后1个不重复结点为当前结点(sentry->next=cur;sentry=cur;),直到整个链表遍历结束。最后将最后1个不重复结点的下1个结点置空。

  • 复杂度分析

    假设链表长度为n,则时间复杂度为$O(n)$、空间复杂度为$O(1)$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head==nullptr)
return nullptr;
ListNode* sentry=head, *cur=head;
while(cur!=nullptr){
if(sentry->val != cur->val){
sentry->next = cur;
sentry = cur;
}
cur = cur->next;
}
sentry->next=nullptr;
return head;
}
};

题解四

解题思路

  • 迭代法

    遍历链表,如果当前结点与下1个结点通知则删除下1个结点,否则更新下1个结点。

    该思路与题解三的思路有相同也有不同,相同之处是都保存当前最后1个不重复结点,区别是题解三是一次性删除多个重复结点,而该方法是遇到1个重复结点则直接删除(1次删除1个结点)。

  • 复杂度分析

    • 假设链表长度为n,则时间复杂度为$O(n)$、空间复杂度为$O(1)$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head==nullptr)
return head;
ListNode* cur=head, *next;
while((next=cur->next)!=nullptr)
if (cur->val==next->val)
cur->next = next->next;
else
cur = next;
return head;
}
};

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!