返回
从排序链表中移除重复元素 II:Python 指南
前端
2023-10-02 08:54:35
导言
链表是一种广泛使用的数据结构,由一系列按顺序连接的节点组成。在某些情况下,链表中可能包含重复的元素。在这些情况下,删除重复元素以维护数据的完整性和一致性至关重要。
方法
哑结点法
哑结点是一种虚拟节点,它被添加到链表的开头,以简化对边界条件的处理。
- 创建一个哑结点,并将它的 next 指针指向头结点。
- 初始化两个指针:
prev
指向哑结点,curr
指向头结点。 - 遍历链表,直到
curr
为空:- 如果
curr.val
与prev.val
相等,则将prev.next
指向curr.next
,跳过curr
。 - 否则,将
prev
移动到curr
。
- 如果
- 返回哑结点的 next 指针,因为它现在指向去除了重复元素的链表。
def remove_duplicates_with_dummy(head):
dummy = ListNode(0, head)
prev = dummy
curr = head
while curr:
if curr.val == prev.val:
prev.next = curr.next
else:
prev = curr
curr = curr.next
return dummy.next
迭代法
迭代法类似于哑结点法,但不需要创建一个额外的哑结点。
- 初始化两个指针:
prev
指向空,curr
指向头结点。 - 遍历链表,直到
curr
为空:- 如果
prev
为空或curr.val
与prev.val
相等,则跳过curr
。 - 否则,将
prev
移动到curr
。
- 如果
- 返回
prev
指针,因为它现在指向去除了重复元素的链表。
def remove_duplicates_iteratively(head):
prev = None
curr = head
while curr:
if prev is None or curr.val != prev.val:
prev = curr
else:
prev.next = curr.next
curr = curr.next
return prev
递归法
递归法使用分而治之的方法来解决问题。
- 如果链表为空或只有一个元素,则返回链表。
- 否则,检查头结点的值是否与下一个元素的值相等:
- 如果相等,则返回删除头结点的剩余链表。
- 如果不相等,则返回头结点链接到删除下一个元素后的剩余链表。
def remove_duplicates_recursively(head):
if not head or not head.next:
return head
if head.val == head.next.val:
return remove_duplicates_recursively(head.next)
else:
head.next = remove_duplicates_recursively(head.next)
return head
复杂度分析
时间复杂度:对于所有三种方法,时间复杂度都为 O(n),其中 n 是链表中的节点数。这是因为它们都遍历了整个链表一次。
空间复杂度:哑结点法需要 O(1) 的额外空间,而迭代法和递归法不需要额外的空间。
结论
我们讨论了使用 Python 从排序链表中删除重复元素的几种方法。这些方法在时间和空间复杂度上各不相同,你可以根据自己的具体需求选择最适合你的方法。理解这些算法对于处理需要从链表中删除重复元素的实际问题非常重要。