返回

巧夺偷天,力挽狂澜——程序员必刷力扣题之“82. 删除排序链表中的重复元素 II”

前端

题意解析,洞悉难题奥秘

  1. 删除排序链表中的重复元素 II 存在一个按升序排列的链表,给你这个链表的头节点 head,请你删除链表中所有出现超过两次的元素。

例如,对于链表 1->2->3->3->4->4->5,你需要删除所有的 34,最终得到 1->2->5

算法导引,庖丁解牛

为了解决这道难题,我们可以采取以下步骤:

  1. 设置两个指针:currentprev,其中 current 指向当前节点,prev 指向前一个节点。
  2. current 指针从链表头部开始移动。
  3. 如果 current 指针指向的节点的值与 prev 指针指向的节点的值不同,则将 prev 指针移到 current 指针指向的节点。
  4. 如果 current 指针指向的节点的值与 prev 指针指向的节点的值相同,则继续移动 current 指针,直到 current 指针指向的节点的值与 prev 指针指向的节点的值不同。
  5. prev 指针指向的节点从链表中删除。
  6. 重复步骤 3-5,直到 current 指针指向链表的最后一个节点。

代码实现,化繁为简

def delete_duplicates(head):
    """
    删除链表中所有出现超过两次的元素。

    :param head: 链表的头节点
    :return: 删除重复元素后的链表的头节点
    """
    # 设置两个指针:current 和 prev,其中 current 指向当前节点,prev 指向前一个节点。
    current = head
    prev = None

    # 将 current 指针从链表头部开始移动。
    while current:
        # 如果 current 指针指向的节点的值与 prev 指针指向的节点的值不同,则将 prev 指针移到 current 指针指向的节点。
        if prev is None or current.val != prev.val:
            prev = current

        # 如果 current 指针指向的节点的值与 prev 指针指向的节点的值相同,则继续移动 current 指针,直到 current 指针指向的节点的值与 prev 指针指向的节点的值不同。
        else:
            while current and current.val == prev.val:
                current = current.next

        # 将 prev 指针指向的节点从链表中删除。
        prev.next = current

        # 重复步骤 3-5,直到 current 指针指向链表的最后一个节点。
    return head

复杂度分析,以不变应万变

  • 时间复杂度:O(n),其中 n 是链表的长度。这是因为我们需要遍历整个链表。
  • 空间复杂度:O(1),因为我们不需要额外的数据结构。

总结升华,醍醐灌顶

“82. 删除排序链表中的重复元素 II”是一道经典的程序员面试题,它考察了程序员的数据结构与算法功底。通过这道题,我们不仅学习了一种解决问题的算法,还领略到了算法之美。在今后的学习和工作中,我们将不断遇到新的挑战,但只要我们掌握了扎实的基础知识,就能够迎难而上,最终取得成功。