LeetCode(138) Copy List with Random Pointer
2015-11-13 14:05
302 查看
题目
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测试程序源码
相关文章推荐
- window.open和window.showdialog区别
- 如何实现营销型网站推广的终极目标?
- java 服务器架构图 参考地址
- eclipse在Linux下的安装配置maven
- 安装和学习OpenStack--学习资料
- linux下mysql的表名问题
- docker 命令整理
- Linux开机自启动与用户登录自启动
- hadoop-2.7.1启动Unable to load native-hadoop library for your platform问题解决
- centos install android sdk
- Linux系统最近重启时间、错误日志
- Android MVP架构浅析
- tomcat web服务器之请求并发能力
- HDU 1011.Starship Troopers【树上DP】【11月13】
- openwebrtc Dependencies and Licenses
- teamview linux命令行安装参数
- 常见的网站攻击方式(基础)
- linux进程相关函数
- 每日一Linux命令
- [hadoop2.7.1]I/O之压缩