题目

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.

分析

实现一个链表的深拷贝,返回拷贝后的新链表。

若是普通链表,逐个拷贝原始链表节点并连接即可,只需O(n)的时间复杂度;但是此题特殊的是,每个节点都有一个random域可以指向该链表中的任何一个节点,所以直接复制无法处理random域,因为其指向的节点很有可能还没有创建出来。

有两种方法处理:

方法一:暴力解决,首先不处理random域,将原始链表复制一份,然后遍历每个原始链表节点,查找其random域,将新链表的对应节点链接,该方法需要O(n^2)的时间复杂度,给出的结果是TLE。

方法二:充分利用原始链表的信息,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面(参考):



同理分两步

1、构建新节点random指针:

new1->random = old1->random->next, new2-random = NULL,
new3-random = NULL, new4->random = old4->random->next

2、恢复原始链表以及构建新链表:

old1->next = old1->next->next,  new1->next = new1->next->next

该算法时间复杂度O(N),空间复杂度O(1)

AC代码

class Solution {
public:
//方法一:直接复制,再修改random指针
RandomListNode *copyRandomList1(RandomListNode *head) {
if (!head)
return NULL; RandomListNode *ret = new RandomListNode(head->label), *q = ret;
RandomListNode *p = head->next;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
q->next = tmp;
q = q->next; p = p->next;
}//while
q->next = NULL; //处理原始链表的random指针
p = head, q = ret;
RandomListNode *idx1 = head, *idx2 = ret;
while (p)
{
if (p->random == NULL)
q->random = NULL;
else{
idx1 = head;
idx2 = ret;
while (p->random->label != idx1->label)
{
idx1 = idx1->next;
idx2 = idx2->next;
}//while
q->random = idx2;
}//else
p = p->next;
q = q->next;
}//while
return ret;
} //方法二:充分利用原始链表信息,在每个节点后复制添加
RandomListNode *copyRandomList(RandomListNode *head) {
if (!head)
return NULL; //首先,复制原始的节点,连接自身后面
RandomListNode *p = head;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
//保存后续节点
RandomListNode *r = p->next; tmp->next = r;
p->next = tmp; p = r;
}//while //然后,将添加的节点random 链接到原始节点random的下一个位置
p = head;
while (p)
{
RandomListNode *q = p->next;
if (p->random == NULL)
q->random = NULL;
else{
q->random = p->random->next;
}//else
//处理下一个原始节点
p = q->next;
}//while //最后,恢复原始链表,得到新链表
RandomListNode *ret = head->next; p = head;
RandomListNode *q = head->next;
while (q->next)
{
p->next = q->next;
p = q;
if (q->next)
q = q->next;
}
p->next = NULL;
q->next = NULL;
return ret;
} };

GitHub测试程序源码

LeetCode(138) Copy List with Random Pointer的更多相关文章

  1. 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 it ...

  2. 【LeetCode练习题】Copy List with Random Pointer

    Copy List with Random Pointer A linked list is given such that each node contains an additional rand ...

  3. [Leetcode Week17]Copy List with Random Pointer

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

  4. LeetCode(275)H-Index II

    题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...

  5. LeetCode(220) Contains Duplicate III

    题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  6. LeetCode(154) Find Minimum in Rotated Sorted Array II

    题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...

  7. LeetCode(122) Best Time to Buy and Sell Stock II

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

  8. LeetCode(116) Populating Next Right Pointers in Each Node

    题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...

  9. LeetCode(113) Path Sum II

    题目 Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given ...

随机推荐

  1. [RDL]中多行组列组占比报表制作

    结果如下: 生意额占比表达式:=iif(Fields!生意额.Value is nothing,"",Fields!生意额.Value/sum(Fields!生意额.Value, ...

  2. Jquery会死吗?我为什么不用vue写富文本!

    一.事件背景: 我最近开源了一个个人耗时半年打造的富文本及一套适用于web后台的ui框架,在gitee上受到网友们的关注,部分网友对我采用jquery的技术栈提出了质疑.总结起来:无非是jquery已 ...

  3. DetachedCriteria的简单使用

    一. DetachedCriteria使得hibernate能够对查询条件进行面向对象的方式来组装.其创建方式有两种: 1.1直接用class创建:DetachedCriteria criteria  ...

  4. JS将人民币小写金额转换为大写

    /** 数字金额大写转换(可以处理整数,小数,负数) */ function smalltoBIG(n) { var fraction = ['角', '分']; var digit = ['零', ...

  5. ABAP EXCEPTION

    CX_ROOT | |--CX_STATIC_CHECK | |--CX_DYNAMIC_CHECK | | | |--CX_SY_ARITHMETIC_ERROR //运算 '&OPERAT ...

  6. SQL Server Sleeping会话占用内存资源浅析?

      在SQL Server中,会话的状态有运行(Running).睡眠(Sleeping).休眠(Dormant).Preconnect 等状态,有时候你会在数据库中看到很多会话处于睡眠(Sleepi ...

  7. MATLAB中容易忽略却经常遇到的小技巧总结

    1       如何产生一个列向量相同的矩阵 例如,列向量x=[1;2;3],要产生矩阵A=[x,x,x],即[1,1,1;2,2,2;3,3,3]. A = repmat(x,1,n) 2      ...

  8. Countup.js:vue-countup-v2(npm)数字滚动插件

    1.官方地址:http://inorganik.github.io/countUp.js/ 2.官方demo: 3.参数说明: params——start(开始数字).end(结束数字).decima ...

  9. 洛谷 P1588 丢失的牛

    题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走到2*x的位置.计算他 ...

  10. Failed to load property source from location 'classpath:/applica)

    : 1.注释错误(application.yml用的是#注释) 2.缩进采用tab而不是空格引起的(不同配置之间也不能有tab出现,否则会报错) 3.冒号后面必须有空格否则会报错