返回
LeetCode 83:扫清重复,筑就有序单链表
前端
2023-10-31 00:40:23
LeetCode 83:扫清重复,筑就有序单链表
在计算机科学领域,链表是一种常见的数据结构,由一系列按特定顺序排列的节点组成,每个节点包含数据和指向下一个节点的指针。当我们处理有序数据时,链表通常是理想的选择,它可以高效地进行元素的插入、删除和查找操作。
LeetCode 83题正是针对有序单链表的一道经典算法题,题目要求我们删除链表中所有重复的元素,使每个元素只出现一次。乍看之下,这似乎是一项艰巨的任务,但通过精心设计的算法,我们可以巧妙地解决这个问题。
算法详解
为了删除链表中的重复元素,我们需要一个巧妙的策略,可以帮助我们快速识别和跳过重复元素。为此,我们引入三个指针:
- 当前指针(current):指向当前正在处理的节点。
- 前驱指针(prev):指向当前指针的前一个节点。
- 辅助指针(helper):用于遍历链表,帮助我们查找重复元素。
算法的核心思想是,当我们遇到一个重复元素时,我们使用辅助指针找到下一个不重复的元素,然后将当前指针指向该元素,同时将前驱指针指向当前指针,从而跳过重复元素。
具体步骤如下:
- 初始化三个指针:当前指针current指向链表的头节点head,前驱指针prev指向空节点,辅助指针helper指向链表的头节点head。
- 循环遍历链表,直到当前指针current指向空节点:
- 如果当前指针current指向的元素与辅助指针helper指向的元素相同,则说明找到了一个重复元素。
- 将辅助指针helper向前移动一位,继续查找下一个不重复的元素。
- 将前驱指针prev指向当前指针current,以便跳过重复元素。
- 将当前指针current指向辅助指针helper指向的元素,完成一个元素的处理。
- 重复步骤2和步骤3,直到辅助指针helper指向空节点。
代码实现
def deleteDuplicates(head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 初始化三个指针
current = head
prev = None
helper = head
# 循环遍历链表
while current:
# 如果找到重复元素
if helper and current.val == helper.val:
# 将辅助指针向前移动一位
helper = helper.next
# 将前驱指针指向当前指针
prev = current
# 将当前指针指向下一个不重复的元素
current = helper
# 如果没有找到重复元素
else:
# 将前驱指针指向当前指针
prev = current
# 将当前指针指向下一个元素
current = current.next
# 将辅助指针指向当前指针
helper = current
# 返回链表头节点
return head
复杂度分析
该算法的时间复杂度为O(n),其中n为链表的长度。这是因为辅助指针helper需要遍历整个链表一次,而当前指针current和前驱指针prev最多需要遍历链表两次。因此,算法的总时间复杂度为O(n)。
算法的空间复杂度为O(1),因为我们只需要使用三个指针,它们所占用的空间是常数。
结语
LeetCode 83题是一道经典的算法题,它考验了我们对链表的理解和操作能力。通过精心设计的算法,我们可以巧妙地删除链表中的重复元素,使每个元素只出现一次。希望这篇指南能够帮助您解决LeetCode 83题,并为您的算法学习之旅锦上添花。