返回

利用双指针技术,巧妙解决LeetCode 83题:删除排序链表中的重复元素

后端

算法:
我们使用两个指针来遍历链表:

  1. 第一个指针 current 用于遍历链表中的节点。
  2. 第二个指针 previous 用于指向当前节点的前一个节点。

当我们遇到一个重复的节点时,我们将其从链表中删除。具体方法是将 previous 指针指向当前节点的下一个节点,跳过当前节点。

以下是使用双指针技术删除排序链表中重复元素的详细步骤:

  1. 初始化 currentprevious 指针,均指向链表的头节点。

  2. 遍历链表,使用 current 指针依次指向每个节点。

  3. 如果 current 指向的节点与 previous 指向的节点值相等,则表明该节点是重复的。

  4. previous 指针指向 current 指向的节点的下一个节点,跳过 current 指向的节点。

  5. current 指针指向 current 指向的节点的下一个节点。

  6. 重复步骤 2-5,直到 current 指针到达链表的尾节点。

  7. 返回 previous 指向的节点,即删除重复元素后的链表的头节点。

实现:

def delete_duplicates(head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    # 初始化 current 和 previous 指针
    current = head
    previous = None

    # 遍历链表
    while current:
        # 如果 current 指向的节点与 previous 指向的节点值相等,则表明该节点是重复的
        if previous and previous.val == current.val:
            # 将 previous 指针指向 current 指向的节点的下一个节点,跳过 current 指向的节点
            previous.next = current.next
        else:
            # 否则,将 previous 指针指向 current 指向的节点
            previous = current

        # 将 current 指针指向 current 指向的节点的下一个节点
        current = current.next

    # 返回 previous 指向的节点,即删除重复元素后的链表的头节点
    return head

复杂度分析:

  • 时间复杂度:O(n),其中 n 是链表中的节点数。这是因为我们遍历了链表一次,并且删除每个重复节点的开销是常数。
  • 空间复杂度:O(1),因为我们没有使用额外的空间来存储数据。