您的位置:首页 > 运维架构

leetcode -- Copy List with Random Pointer

2013-10-05 15:42 477 查看
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.

[解题思路]

1.和clone graph那题差不多,使用一个map来保存已经创建好的node。

第一步:先复制原始链表中的节点,用next指针链接起来,在复制节点时放入map中

第二步:设置每个节点的random指针

空间复杂度为O(n),时间复杂度为O(n)

Accepted Code

public RandomListNode copyRandomList(RandomListNode head) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(head == null){
return head;
}

Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
RandomListNode newHead = new RandomListNode(head.label);
map.put(head, newHead);
RandomListNode p1 = head;
RandomListNode p2 = newHead;
p1 = p1.next;
// p2 = p2.next;

while(p1 != null){
RandomListNode tmp = new RandomListNode(p1.label);
p2.next = tmp;
map.put(p1, tmp);
p1 = p1.next;
p2 = p2.next;
}

p1 = head;
p2 = newHead;
while(p1 != null){
RandomListNode random = p1.random;
if(random != null)
p2.random = map.get(random);
p1 = p1.next;
p2 = p2.next;
}

return newHead;
}


2.上面的做法使用map的意义在于设置random指针时可以直接从map中找到,但使用map会带来O(n)的空间消耗

换个思路:第一步仍然根据原始链表的每个结点n创建相应的n'。将n'链接到n后面



第二步设置n'的random指针。n'的random指针所指向的结点是n的random指针所指向的结点的下一个结点

第三步把第二步得到的链表拆成两个链表

public class Solution {

public RandomListNode cloneNodes(RandomListNode head){
RandomListNode p1 = head;
while(p1 != null){
RandomListNode c1 = new RandomListNode(p1.label);
c1.next = p1.next;
p1.next = c1;
p1 = c1.next;
}
return head;
}

public RandomListNode setRandomPointer(RandomListNode head){
RandomListNode p1 = head;
while(p1 != null){
RandomListNode r1 = p1.random;
if(r1 != null){
p1.next.random = r1.next;
}
p1 = p1.next.next;
}
return head;
}

public RandomListNode reconnectNodes(RandomListNode head){
RandomListNode cloneHead = head.next;
RandomListNode p1 = head;
RandomListNode p2 = cloneHead;
while(p1 != null && p2 != null){
p1.next = p2.next;
p1 = p1.next;
if(p1 != null){
34                 p2.next = p1.next;
35             }
p2 = p2.next;
}
return cloneHead;
}

public RandomListNode copyRandomList(RandomListNode head) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(head == null){
return head;
}

cloneNodes(head);
setRandomPointer(head);
return reconnectNodes(head);
}
}


ATT:拆成两个链表时,当处理到最后一个节点时需要注意


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: