📅  最后修改于: 2023-12-03 15:40:01.447000             🧑  作者: Mango
此题是关于链表的操作问题,需要删除链表中重复出现的节点。
给定一个单链表的头节点 head
,请你删除其中所有重复出现的节点,只留下原始链表中没有重复出现的节点。
例如:
输入:1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5
输出:1 -> 2 -> 5
输入:1 -> 1 -> 1 -> 2 -> 3
输出:2 -> 3
链表节点的数据类型定义如下:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
最简单的方法就是使用一个 hashmap 来记录每个节点出现的次数,再遍历链表将出现次数大于 1 的节点删除。
这里我们介绍两种不同的解法,一种是递归,一种是迭代。
递归解法看起来简单明了,代码也较为简短。
具体步骤如下:
代码如下:
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
if head.val == head.next.val:
val = head.val
while head and head.val == val:
head = head.next
return self.deleteDuplicates(head)
else:
head.next = self.deleteDuplicates(head.next)
return head
迭代解法需要我们使用一些额外的指针,可以写得比较简洁。
具体步骤如下:
prev
,cur
和 next
,分别指向当前节点的前一个节点、当前节点和当前节点的下一个节点。cur
和 next
。prev
指向 cur
,cur
指向 next
,再将 next
指向 next.next
。代码如下:
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
dummy = ListNode(-1)
dummy.next = head
prev, cur, next = dummy, head, head
while cur:
if cur.next and cur.next.val == cur.val:
val = cur.val
while cur and cur.val == val:
cur = cur.next
prev.next = cur
next = cur
else:
prev = cur
cur = next
if next:
next = next.next
return dummy.next
对于两种解法的时间复杂度都是 $O(n)$,其中 $n$ 是链表的长度,因为我们每个节点只会遍历一遍,所以时间复杂度为线性。
空间复杂度上,递归解法的空间复杂度是 $O(n)$,因为我们每次递归都会使用到栈空间。而迭代解法的空间复杂度是 $O(1)$,因为我们只需要常数级别的额外空间。