返回

LeetCode 06:复制带随机指针的链表,详解深度拷贝之妙**

前端

前奏:探索链表的奥秘

链表是一种线性的数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在普通链表中,每个节点只指向下一个节点,没有额外的指针。然而,在带随机指针的链表中,每个节点除了指向下一个节点的指针外,还包含指向随机节点的指针。

06 号关卡:复制随机指针的链表

LeetCode 06 挑战我们复制一个带随机指针的链表,要求是深度拷贝,这意味着副本链表中的每个节点都应该有自己的数据和指针,而不是指向原链表中的节点。这个难题的精髓在于巧妙地复制随机指针,因为它们可能会指向链表中的任意节点。

算法策略:步步为营

  1. 构建副本链表: 首先,我们需要创建副本链表,其中包含与原链表相同数量的节点。我们可以使用哈希表来记录原链表中的每个节点与其副本之间的对应关系。
  2. 复制数据: 接下来,我们将原链表中的数据逐个复制到副本链表中,同时更新副本链表中节点之间的 next 指针。
  3. 复制随机指针: 最后,我们遍历原链表和副本链表,使用哈希表查找每个原节点对应的副本节点,并更新副本节点的 random 指针。

示例代码:清晰解析

class Solution {
    public Node copyRandomList(Node head) {
        // 哈希表用于记录原节点与副本节点之间的对应关系
        Map<Node, Node> map = new HashMap<>();
        Node newHead = new Node(head.val);
        map.put(head, newHead);
        
        Node curr = head, newCurr = newHead;
        // 复制数据和 next 指针
        while (curr != null) {
            newCurr.next = new Node(curr.next.val);
            map.put(curr.next, newCurr.next);
            curr = curr.next;
            newCurr = newCurr.next;
        }
        
        curr = head;
        newCurr = newHead;
        // 复制 random 指针
        while (curr != null) {
            newCurr.random = map.get(curr.random);
            curr = curr.next;
            newCurr = newCurr.next;
        }
        
        return newHead;
    }
}

深入洞察:算法之美

这个算法的关键在于使用哈希表来跟踪原节点和副本节点之间的对应关系。这样,在复制随机指针时,我们可以直接从哈希表中查找对应的副本节点,大大提高了效率。

总结:算法的艺术

LeetCode 06 是一道巧妙而具有挑战性的算法题。通过逐步解析其解决方案,我们了解到如何巧妙地复制带随机指针的链表,加深了对链表和算法的理解。不断磨练算法技能,你将在编程的道路上取得更大的成功。