[LeetCode] Copy List with Random Pointer 拷贝带有随机指针的链表

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

Return a deep copy of the list.

这道链表的深度拷贝题的难点就在于如何处理随机指针的问题,由于每一个节点都有一个随机指针,这个指针可以为空,也可以指向链表的任意一个节点,如果我们在每生成一个新节点给其随机指针赋值时,都要去便利原链表的话,OJ上肯定会超时,所以我们可以考虑用Hash map来缩短查找时间,第一遍遍历生成所有新节点时同时建立一个原节点和新节点的哈希表,第二遍给随机指针赋值时,查找时间是常数级。代码如下:

方法一:

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if (!head) return NULL;
        RandomListNode *res = new RandomListNode(head->label);
        RandomListNode *node = res;
        RandomListNode *cur = head->next;
        map<RandomListNode*, RandomListNode*> m;
        m[head] = res;
        while (cur) {
            RandomListNode *tmp = new RandomListNode(cur->label);
            node->next = tmp;
            m[cur] = tmp;
            node = node->next;
            cur = cur->next;
        }
        node = res;
        cur = head;
        while (node) {
            node->random = m[cur->random];
            node = node->next;
            cur = cur->next;
        }
        return res;
    }
};

当然,如果使用哈希表占用额外的空间,如果这道题限制了空间的话,就要考虑别的方法。下面这个方法很巧妙,具体细节可参见神网友水中的鱼的博客,该方法可以分为以下三个步骤:

1. 在原链表的每个节点后面拷贝出一个新的节点

2. 依次给新的节点的随机指针赋值,而且这个赋值非常容易 cur->next->random = cur->random->next

3. 断开链表可得到深度拷贝后的新链表

代码如下:

方法二:

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if (!head) return NULL;
        RandomListNode *cur = head;
        while (cur) {
            RandomListNode *node = new RandomListNode(cur->label);
            node->next = cur->next;
            cur->next = node;
            cur = node->next;
        }
        cur = head;
        while (cur) {
            if (cur->random) {
                cur->next->random = cur->random->next;
            }
            cur = cur->next->next;
        }
        cur = head;
        RandomListNode *res = head->next;
        while (cur) {
            RandomListNode *tmp = cur->next;
            cur->next = tmp->next;
            if(tmp->next) tmp->next = tmp->next->next;
            cur = cur->next;
        }
        return res;
    }
};
时间: 2024-10-26 07:22:31

[LeetCode] Copy List with Random Pointer 拷贝带有随机指针的链表的相关文章

Copy List with Random Pointer复制带有随机指针的链表

这道题目很经典,很多书和OJ里都有.如果初次遇到,一定很难搞定.再看其解法,实在是很惊艳. 有两个可以得到深刻启示的地方: (1)冗余的思想.谈到复制,我们往往都会另起炉灶,而不会原来链表上搞来搞去,感觉很复杂很危险,会一团糟.美错,最危险的地方就是最安全的地方. (2)指针的步伐.这里的指针有一走两步的操作,很容易导致RE.但是否意味着每步都要仔细考虑指针越界?不然,那样程序会写的很累很乱.还是按照最初的想法,谨慎实现之.回头查看特殊情况,例如空指针情况.只有一个节点的情况,用实际用例去测试,

[leetcode]138. Copy List with Random Pointer复制带有随机指针的链表

public RandomListNode copyRandomList(RandomListNode head) { /* 深复制,就是不能只是复制原链表变量,而是做一个和原来链表一模一样的新链表, 每一个节点都是新建的,而不是指向就节点 这个题的难点在于:随机节点. 随机节点有可能指向后边还没有建立的节点,这就没法指. 方法一:一一对应地记录每个新旧节点的映射关系,在常规节点建立后,就去查哈希表,找到对应 新节点的旧节点的random,就是新节点的random */ if (head==nu

LeetCode: Copy List with Random Pointer [138]

[题目] A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. [题意] 给定一个链表,每个节点除了next指针外,还有一个random指针,指向任意的节点. 要求,复制这样的一个链表 [思路] 思路1: 先一次生成每个节点对

[leetcode]Copy List with Random Pointer @ Python

原题地址:https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题意: A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. 解题思路:这题主要是需要深

LeetCode——Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. 原题链接:https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题目:给定一个链表,当中的每一个节

133. Clone Graph 138. Copy List with Random Pointer 拷贝图和链表

133. Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node lab

九章算法面试题57 拷贝带随机指针的链表结构

九章算法官网-原文网址 http://www.jiuzhang.com/problem/57/ 题目 给出一条带随机指针的链表,对其进行深度拷贝(Deep Copy). 带随机指针的意思是,对于每个节点,除了next指针指向下一个节点以外,还带一个randomNext指针指向任何一个链表中的节点或空. 深度拷贝的意思是,对于新复制出来的链表,是一条完全独立于原来链表的链表,对于这个新的链表进行任何操作都不会对原来的链表产生影响. Follow Up Question: 如果不能使用额外的辅助空间

LeetCode138 Copy List with Random Pointer(深度复制带有随机指针的链表) Java题解

题目: A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. 解题: 这题是要复制一个链表,这个链表比普通的链表多一个指针,这个指针可以指向任意地方,可以为空也可以为链表中的任一个节点,今天中午的时候我同学和我说起这题,当时问

leetcode - Copy List with Random Pointer题解

链表格式 通常链表就是一个值,一个next指针,指向后面的节点. 结构体如下: struct Node{ int val; struct Node* next; } 这个题目里的节点多了一个指针,除了指向下一个节点的next指针,还有一个指向这个链表随机一个节点的random指针. 结构体如下: struct Node{ int val; struct Node* next; struct Node* random; } 普通链表值拷贝 通常我们拷贝链表的时候,进行值拷贝,只用从头开始遍历就可以