Copy List with Random Pointer
来源:互联网 发布:淘宝试用如何领取 编辑:程序博客网 时间:2024/06/05 02:29
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.
public RandomListNode copyRandomList(RandomListNode head)
这一题,最直观的做法就是HashMap,键放的是原list的元素,值放的是克隆出来的元素。不管是遇到random pointer还是next pointer的时候先看看指向的对象是否存在于HashMap中,如果存在,就直接返回值域的内容。否则就克隆内容并将键值对放进HashMap中。下面给出对应的代码:
public RandomListNode copyRandomList(RandomListNode head) { HashMap<RandomListNode, RandomListNode> orig_to_copy = new HashMap<RandomListNode, RandomListNode>(); RandomListNode tmp = head, res = null, copy_tmp = null; while(tmp != null){ RandomListNode copy = new RandomListNode(tmp.label); orig_to_copy.put(tmp, copy); res = res == null ? copy : res; if(tmp == head){ copy_tmp = copy; }else{ copy_tmp.next = copy; copy_tmp = copy_tmp.next; } tmp = tmp.next; } tmp = head; while(tmp != null){ if(tmp.random != null){ orig_to_copy.get(tmp).random = orig_to_copy.get(tmp.random); } tmp = tmp.next; } return res; }
这段代码的逻辑和上述算法有一点点不同,这段代码是将原链表跑两遍,第一遍是纯复制普通链表,第二遍是连接random pointer,本质和我刚才描述的算法没有不同,只是这样处理在第一个while循环里,逻辑会比较简单一些。
但这并不是最优的算法,最优的算法是这样的。
第一步,以正常链表的方式克隆并且以一种合并的状态合成一个链表。合并的方式是这样的,原链表当前节点的下一个插入自己的克隆节点。这样就会构成下面这样的链表
A->A`->B->B`->C->C`....其中X`是X的克隆。
第二步,再以这样的链表复制random pointer,在这种形态里,当前原链表的节点的random pointer指向的对象的下一个对象就是该节点克隆该指向的对象。
也就是假如A指向C,那么A`一定指向C`,也就是C的下一个节点。所以A`的random Pointer也就很好分配了。
第三步,链接完所有克隆的random node之后,进行分拆。将奇数位的node作为原链表,偶数位的node作为克隆链表分拆成两个链表,返回第二个即可。
public RandomListNode copyRandomList(RandomListNode head) { // Good solution RandomListNode res_head = null, res_tmp = null, tmp = head; while(tmp != null){//第一步 RandomListNode copy = new RandomListNode(tmp.label); copy.next = tmp.next; tmp.next = copy; res_head = res_head == null ? copy : res_head; tmp = tmp.next.next; } tmp = head; while(tmp != null){//第二步 if(tmp.random != null){ tmp.next.random = tmp.random.next; } tmp = tmp.next.next; } tmp = head; res_tmp = res_head; while(tmp != null){//第三步 tmp.next = tmp.next.next; if(res_tmp.next != null) res_tmp.next = res_tmp.next.next; tmp = tmp.next; res_tmp = res_tmp.next; } return res_head; }
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Copy List with Random Pointer
- Contingency and Management Reserve
- 更新字典(Updating a Dictionary)
- oracle的linesize名令
- linux下有关用户、组以及权限的学习
- Java并发学习笔记(七)-ArrayBlockingQueue
- Copy List with Random Pointer
- HttpRuntime的认识与加深理解
- 算法入门->插入排序->C/C++ 语言实现
- 读《大道至简-软件工程实践者的思想》
- 胜利大逃亡(续)(状态压缩+三维BFS)
- 内部类详解
- ES学习笔记2-理论进阶篇1
- linux 基础
- 黑马程序员---从头开始,回忆JAVA基础之通信(二)