题目: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.

分析:

题目给出了一个特殊的单链表。链表的每一个节点多了个指针域: random. 随机只向链表的某一个 node。

题目要求我们给出这个链表的一个 deep copy.

首先,何为 deep copy ??

Part 1:  三种 Object Copy 的对比(以 Array 为例)

1. Shallow copy

拷贝时仅仅复制的是 指针 或者 引用, 也就是说 数据仅存在一份。

当然,得到效率的同时,存在的问题就是,如果原来的数据改变了, 复制后的对象也改变了,因为仅仅存在一份数据!!!

Note: 其实是出于效率的考虑,在某些场合,并不需要多份数据时,可以采用 shallow copy

2. Deep copy

与 shallow copy 不同,deep copy 复制后,数据有多份。因此, deep copy 也比较费时。

在 C++ 中,可以自行定义类的 copy 构造函数来实现 deep copy.

Python 中,array 默认的复制是 shallow copy,  可以采用 copy 模块的 deep copy

3. Lazy copy

这是一种上述两种策略的组合。又称为 copy-on-write.

最初复制时,采用效率更高的 shallow copy,  同时用一个计数器 counter 记录当前share数据的对象数目。

当需要对数据进行修改时,根据 counter, 采用 deep-copy,

也就是当需要 deep-copy  时,才调用比较费时的 deep-copy.

回归本题:deep copy of the list

对于正常的单链表, 一份 deep copy 非常的容易。只要对链表循环一次,依次复制节点即可。

但是问题的困难在于: Node 多了一个 random 指针域。

对于 random 域:

如果 原链表: Node i 指向 Node j

新链表: Node i 同样指向 Node j(新链表的node)

如何能够找到新链表每个节点 random 域 所指向的节点呢??

思路: Step 1: 首先指向在原链表的每个节点后面,复制一个新的节点,原链表长度变为 2 倍

random 指针指向的是 原链表节点 random 指针指向的节点的后面的那个节点

Step 2: 将链表拆成两个 lists

/**
* 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) {
RandomListNode *tHead = head;
RandomListNode *next = NULL;
while(tHead)
{
next = tHead->next;
RandomListNode *node = new RandomListNode(tHead->label);
node->next = tHead->next;
//node->random = tHead->random;
tHead->next = node;
tHead= next;
}
tHead = head;
while(tHead)
{
if(tHead->random) tHead->next->random = tHead->random->next;
tHead = tHead->next->next;
}
RandomListNode *retHead = NULL;
RandomListNode *tRet = NULL; tHead = head;
RandomListNode *next2 = NULL;
while(tHead)
{
if(retHead == NULL)
{
next2 = tHead->next->next;
retHead = tHead->next;
tRet = retHead;
tHead->next = next2;
tHead = next2;
}
else
{
next2 = tHead->next->next;
tRet->next = tHead->next;
tHead->next = next2;
tHead = next2;
tRet = tRet->next;
} }
return retHead;
}
};

LeetCode----Copy List with Random Pointer 深度拷贝,浅度拷贝,Lazy拷贝解析的更多相关文章

  1. [Leetcode] Copy list with random pointer 对带有任意指针的链表深度拷贝

    A linked list is given such that each node contains an additional random pointer which could point t ...

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

    A linked list is given such that each node contains an additional random pointer which could point t ...

  3. Leetcode Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  4. Leetcode Copy List with Random Pointer(面试题推荐)

    给大家推荐一道leetcode上的面试题,这道题的详细解说在<剑指offer>的P149页有思路解说.假设你手头有这本书.建议翻阅. 题目链接 here A linked list is ...

  5. LeetCode——Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  6. [leetcode]Copy List with Random Pointer @ Python

    原题地址:https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题意: A linked list is given such ...

  7. LeetCode – Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  8. LeetCode——Copy List with Random Pointer(带random引用的单链表深拷贝)

    问题: A linked list is given such that each node contains an additional random pointer which could poi ...

  9. [LeetCode]Copy List with Random Pointer &amp;Clone Graph 复杂链表的复制&amp;图的复制

    /** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label ...

  10. [Leetcode Week17]Copy List with Random Pointer

    Copy List with Random Pointer 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/copy-list-with-random- ...

随机推荐

  1. JavaScript开发者常忽略或误用的七个基础知识点

    JavaScript 本身可以算是一门简单的语言,但我们也不断用智慧和灵活的模式来改进它.昨天我们将这些模式应用到了 JavaScript 框架中,今天这些框架又驱动了我们的 Web 应用程序.很多新 ...

  2. 近期十大优秀jQuery插件推荐

    当有限的开发知识限制了设计进展,你无法为自己插上创新的翅膀时,jQuery可以扩展你的视野.本文将推荐从jQuery网站的Plugin频道中推选出的近期十款优秀jQuery插件. 1.jQuery U ...

  3. HTML5自学笔记[ 20 ]canvas绘图实例之绘制倒影

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  4. BeautifulSoup 常用方法

    #输出所得标签的‘’属性值 获取 head里面的第一个meta的content值 soup.head.meta['content'] 获取第一个span的内容 soup.span.string 获取第 ...

  5. CentOS 6.x启动时网卡eth0未激活

    简述 安装CentOS 6.x操作系统后,开机时发现没有网络,最后发现系统启动时未激活网卡 - 因为只有在激活状态的网卡才能去连接网络,进行网络通讯. 简述 激活网卡eth0 激活网卡eth0 执行& ...

  6. ubuntu14.04LS中安装SSH

    我只能说: 蛋疼了 因为 1.曾经12.04和13.10的源已经不能使用了(PS毕竟支持的时间到了) 2网上有好多说是更新源的 , 打开etc/...文件 ,然后粘贴一下他们给的源的地址 或许有些是可 ...

  7. LINUX 硬盘命令

    1. 查看硬盘情况fdisk -l 每个Disk 为一个硬盘2. 挂在新硬盘fdisk /dev/sdb #硬盘地址Command (m for help):n #新建立分区Command actio ...

  8. BZOJ4007 [JLOI2015]战争调度

    根本想不出来... 原来还是暴力出奇迹啊QAQ 无限ymymym中 /************************************************************** Pr ...

  9. BZOJ一天提交 51纪念(二)

    今天作死又交了一发呢...于是屯题就全用完啦~ 有一次拷错CE,还有一次本来的程序就是错的的说... 可是我希望看到我努力的人并不会看到我的努力呢,尽管如此一个人也要坚持走到底哦,就如同这不完美的提交 ...

  10. GL10控制图形旋转

    GL10提供了glRotatef(float  angle , float  x ,  float  y , float  z)方法,该方法用于控制旋转,该方法种angle控制旋转角度:而x.y.z参 ...