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.
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
这题我第一眼看上去觉得很简单。直接扫描一遍,copy 一个节点的label, next, random不就行了吗?
方法I:图片来自:http://www.cnblogs.com/TenosDoIt/p/3387000.html
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null) return null;
//first copy each node and insert the new nodes to the old ones, one by one
RandomListNode p = head;
while(p != null){
RandomListNode copy = new RandomListNode(p.label);
copy.next = p.next;
p.next = copy;
p = copy.next;
}
//then copy the random links
p = head;
while(p != null){
//don't forget to check if p.random != null
if(p.random != null){
p.next.random = p.random.next;
}
p = p.next.next;
}
//split the new list with the old
p = head;
RandomListNode newHead = head.next;
while(p !=null && p.next !=null){
RandomListNode temp = p.next;
p.next = temp.next;
p = temp;
}
return newHead;
}
}
方法II: 使用一个HashMap 存储新旧节点之间的对应关系. 这样我们就可以根据旧节点的Random link 找到新节点的Random link.
public class Solution {
//use a hashMap to store the mapping relationship between old nodes and new nodes
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null) return null;
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
//first create new nodes
//why can't we put this part into the while?
RandomListNode newHead = new RandomListNode(head.label);
RandomListNode p = head;
RandomListNode q = newHead;
map.put(head, newHead);
p = p.next;
while(p != null){
RandomListNode copy = new RandomListNode(p.label);
map.put(p, copy);
q.next = copy;
q = copy;
p = p.next;
}
//create random links
p = head;
q = newHead;
while(p!=null){
if(p.random != null){
q.random = map.get(p.random);
}
p = p.next;
q = q.next;
}
return newHead;
}
}
Note: 第二遍我有思路,知道应该插入新节点,并分拆两个链表。