返回
巧用「递归 + 双指针」,斩获 LeetCode「删除排序链表中的重复元素 II」难题
IOS
2024-01-29 19:47:50
在 LeetCode 中,「删除排序链表中的重复元素 II」问题要求我们删除链表中重复出现的元素,并保留其第一次出现的节点。相较于「删除排序链表中的重复元素」问题,本题的难点在于需要删除所有重复出现的元素 。
为了应对这个挑战,本文将介绍一种巧妙的「递归 + 双指针」方法。这种方法通过递归和双指针技术,以优雅的方式解决问题,展现其高效性。
算法详解
「递归 + 双指针」方法
该方法包含以下关键步骤:
-
创建两个指针:
current
指针指向当前节点。prev
指针指向current
的前一个节点。
-
递归处理余下链表:
- 使用递归调用
removeDuplicates()
函数处理当前节点之后的链表。
- 使用递归调用
-
比较当前元素和下一个元素:
- 如果
current.val
等于current.next.val
,则存在重复。
- 如果
-
删除重复元素:
- 如果存在重复,则将
prev.next
指向current.next.next
,从而跳过重复元素。
- 如果存在重复,则将
-
移动指针:
- 如果不存在重复,则将
prev
和current
指针向后移动一位。
- 如果不存在重复,则将
-
递归返回:
- 递归返回
prev.next
,表示删除重复元素后的链表。
- 递归返回
代码实现
def removeDuplicates(head):
if not head or not head.next:
return head
prev = None
current = head
while current:
if current.val == prev.val:
prev.next = current.next
else:
prev = current
current = current.next
return head
实例演示
考虑如下链表:
1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5
使用上述算法,我们可以逐步删除重复元素:
- 首先,我们比较
1
和2
,发现它们不重复,所以移动指针。 - 接下来,比较
2
和3
,发现它们重复,所以跳过3
。 - 继续比较
2
和4
,发现它们重复,所以再次跳过4
。 - 最后,比较
2
和5
,发现它们不重复,所以移动指针。
最终,我们得到的结果链表:
1 -> 2 -> 5
优点
- 高效:通过递归和双指针技术,该方法在时间复杂度上达到 O(n),其中 n 为链表的长度。
- 易于理解:算法逻辑清晰简单,易于理解和实现。
- 适用于各种场景:该方法适用于删除任何类型有序链表中的重复元素,不仅限于整数链表。
总结
「递归 + 双指针」方法巧妙地解决了 LeetCode「删除排序链表中的重复元素 II」难题。通过递归处理链表,并使用双指针跳过重复元素,该方法高效且易于理解。这种方法展示了算法思维的精髓,并为解决其他类似问题提供了宝贵的参考。