返回

解读 LeetCode 138:复制带随机指针的链表的极致之道

见解分享

在解决算法难题的世界中,LeetCode 138 以其复杂性和巧妙的解法而闻名。复制带随机指针的链表这一问题要求我们复制一个单链表,其中每个节点除了指向下一个节点的指针外,还包含一个指向链表中任意节点的随机指针。

探索问题本质

理解 LeetCode 138 的关键在于认识到问题的独特之处。传统的链表复制仅涉及复制节点值和下一个指针,而这里的随机指针增加了额外的复杂性。它迫使我们找到一种方法,不仅要复制节点,还要保持随机指针在复制链表中的对应关系。

哈希表闪耀登场

为了解决这个问题,我们借助于哈希表的数据结构。哈希表允许我们以键值对的形式存储和检索数据,键通常是对象的引用。在本例中,我们将旧链表的节点指针作为键,而新链表的节点指针作为值。

解决方案精髓

解决方案分为两个阶段:

  1. 第一次遍历: 在第一次遍历中,我们复制链表的节点值,创建新链表,并将旧链表节点指针与新链表节点指针之间的对应关系存储在哈希表中。

  2. 第二次遍历: 在第二次遍历中,我们访问旧链表的随机指针,然后使用哈希表查找其对应的新链表节点的随机指针,并将其赋予新链表的对应节点。

代码示例

为了清晰起见,我们以 Python 代码为例:

def copyRandomList(head):
    # 哈希表,键为旧链表节点,值为新链表节点
    hashmap = {}

    # 新链表的头节点
    new_head = Node(head.val)

    # 初始化新链表的头节点
    new_curr = new_head

    # 遍历旧链表
    curr = head
    while curr:
        # 创建新链表节点
        new_curr.next = Node(curr.val)

        # 将对应关系存储在哈希表中
        hashmap[curr] = new_curr.next

        # 移动旧链表和新链表指针
        curr = curr.next
        new_curr = new_curr.next

    # 遍历旧链表
    curr = head
    while curr:
        # 如果存在随机指针
        if curr.random:
            # 通过哈希表获取新链表对应节点的随机指针
            new_curr.random = hashmap[curr.random]

        # 移动旧链表和新链表指针
        curr = curr.next
        new_curr = new_curr.next

    # 返回新链表的头节点
    return new_head

结语

LeetCode 138 是一个巧妙的算法难题,它考验了我们的数据结构和算法知识。通过采用哈希表的巧妙应用,我们能够有效地复制带随机指针的链表,从而解决这一难题。祝愿你在算法探索的道路上继续取得成功!