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;    }


0 0