返回

踏破[LeetCode]138:复制带有随机指针的链表,进击算法巅峰

前端

征服 LeetCode 138:复制带有随机指针的链表

欢迎来到算法世界的冒险之旅,准备好在这一场智力盛宴中释放你的内在潜力吧!今天,我们将深入探讨 LeetCode 138:复制带有随机指针的链表,这是一道极具挑战性的问题,将考验你的算法技能和对链表操作的理解。

了解问题

LeetCode 138:复制带有随机指针的链表 要求你复制一个长度为 n 的链表,每个节点包含一个额外的随机指针 random,该指针可以指向链表中的任何其他节点或 null。复制的链表必须保持与原始链表相同的 nextrandom 指针关系。

分解问题

要解决这个难题,我们可以将其分解成以下步骤:

  1. 创建新节点: 遍历原始链表,为每个节点创建一个新节点。
  2. 建立 next 引用: 为新节点建立与原始链表中节点相同的 next 引用。
  3. 建立 random 引用: 为新节点建立与原始链表中节点相同的 random 引用。

算法实现

struct Node {
    int val;
    Node *next, *random;

    Node(int x) : val(x), next(NULL), random(NULL) {}
};

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if (!head) return nullptr;

        // 创建新节点
        unordered_map<Node*, Node*> oldToNew;
        for (Node* curr = head; curr; curr = curr->next) {
            oldToNew[curr] = new Node(curr->val);
        }

        // 建立 `next` 引用
        for (Node* curr = head; curr; curr = curr->next) {
            oldToNew[curr]->next = oldToNew[curr->next];
        }

        // 建立 `random` 引用
        for (Node* curr = head; curr; curr = curr->next) {
            oldToNew[curr]->random = oldToNew[curr->random];
        }

        return oldToNew[head];
    }
};

算法说明

创建新节点:

  • 使用一个哈希表 oldToNew 将原始节点映射到新节点。
  • 遍历原始链表,为每个节点创建一个新节点,并存储在哈希表中。

建立 next 引用:

  • 遍历原始链表,为新节点建立与原始链表中节点相同的 next 引用。
  • 通过哈希表 oldToNew 查找新节点的 next 引用。

建立 random 引用:

  • 遍历原始链表,为新节点建立与原始链表中节点相同的 random 引用。
  • 通过哈希表 oldToNew 查找新节点的 random 引用。

复杂度分析

  • 时间复杂度: O(n),其中 n 是原始链表中的节点数。
  • 空间复杂度: O(n),哈希表存储新节点的引用。

总结

复制带有随机指针的链表是一项具有挑战性的任务,需要对链表操作和哈希表的深入理解。通过分而治之的方法,我们将问题分解成几个更小的步骤,并使用哈希表高效地建立节点引用。通过实现此算法,你不仅提高了你的算法技能,还增强了你在链表操作方面的信心。