【LeetCode 面试经典150题】138. Copy List with Random Pointer 随机链表的复制

文章描述了如何构建一个链表的深度拷贝,其中每个节点都有额外的随机指针。使用哈希表和递归方法,确保新链表的节点值和指针结构与原链表一致,且新链表中的指针不指向原链表节点。
摘要由CSDN通过智能技术生成

138. Copy List with Random Pointer

题目大意

A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or null.

Construct a deep copy of the list. The deep copy should consist of exactly n brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next and random pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list.

For example, if there are two nodes X and Y in the original list, where X.random --> Y, then for the corresponding two nodes x and y in the copied list, x.random --> y.

Return the head of the copied linked list.

The linked list is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:

  • val: an integer representing Node.val
  • random_index: the index of the node (range from 0 to n-1) that the random pointer points to, or null if it does not point to any node.

Your code will only be given the head of the original linked list.

中文释义

给定一个长度为 n 的链表,每个节点包含一个额外的随机指针,它可能指向链表中的任何节点,或者为 null。

构造这个链表的深度拷贝。深度拷贝应该由完全新的 n 个节点组成,每个新节点的值设置为其对应原始节点的值。新节点的 next 和 random 指针应该指向复制列表中的新节点,使得原始列表和复制列表中的指针表示相同的列表状态。新列表中的指针不应指向原始列表中的节点。

例如,如果原始列表中有两个节点 X 和 Y,其中 X.random --> Y,那么在复制列表中对应的两个节点 x 和 y,x.random --> y。

返回复制链表的头节点。

链表在输入/输出中表示为 n 个节点的列表。每个节点表示为一对 [val, random_index],其中:

  • val:表示 Node.val 的整数
  • random_index:随机指针指向的节点的索引(范围从 0 到 n-1),如果它不指向任何节点,则为 null。

你的代码只会给定原始链表的头节点。

示例

Example 1:
在这里插入图片描述

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]

Example 2:
在这里插入图片描述

Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]

Example 3:
在这里插入图片描述

Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]

限制条件

  • 0 <= n <= 1000
  • -104 <= Node.val <= 104
  • Node.random 为空或指向链表中的某个节点。

解题思路

方法

即深度拷贝一个含有随机指针的链表。该方法使用哈希表和递归。

  1. 使用哈希表缓存节点

    • 创建一个 unordered_map,命名为 cachedNode,用于存储原始节点到新节点的映射。
  2. 递归拷贝

    • 定义 copyRandomList 函数,它接受一个指向链表节点的指针 head
    • 如果 head 为空,返回 nullptr
    • 如果 cachedNode 中不存在 head 的映射,执行以下操作:
      • 创建一个新节点 ans,其值为 head -> val
      • headans 添加到 cachedNode 映射中。
      • 递归地设置 ansnextrandom 指针,分别指向 head -> nexthead -> random 的拷贝。
  3. 返回结果

    • 返回 cachedNode[head],即原始节点 head 对应的新拷贝节点。

代码

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
public:
    unordered_map<Node*, Node*> cachedNode;
    Node* copyRandomList(Node* head) {
        if (head == nullptr) return nullptr;
        if (!cachedNode.count(head)) {
            Node* ans = new Node(head -> val);
            cachedNode[head] = ans;
            ans -> next = copyRandomList(head -> next);
            ans -> random = copyRandomList(head -> random);
        }
        return cachedNode[head];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值