题目链接:https://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.
解题思路:
解法一:
1. 由于 random 指针和 next 指针可能指向已存在的同一个结点,为了避免重复创建新结点,我们将老链表的结点作为键,将新链表对应结点作为值,存放到 HashMap 中。
2. 每次想要创建新结点之前都检查 HashMap 中是否已存在同样的结点。
3. 代码只遍历一次链表,如果它的 next 域不为空,创建新结点(或 HashMap 中找到结点)接到新链表上;random 域同理。
解法二:
1.这种方法与大神的第一种思路类似,不过他要遍历链表两次。
2. 第一次把链表的 next 域补全,第二次补全 random 域。
3. 他这种写法比我的快一点点。
解法三:
1.大神还有第二种解法,不再使用 HashMap 来维护老链表结点和新链表对应结点之间的关系。
2. 而是直接将新链表结点放到老链表对应结点后面,这样既节省了额外空间,又保护了新老结点的对应关系。
3. 所以该解法需遍历链表 3 次,第一次建立新结点,也就是 next 域,第二次扫描补全 random 域,第三次扫描将新链表拆分出来。
附上大神参考链接:http://write.blog.youkuaiyun.com/mdeditor#!postId=50396684
代码实现:
自己的代码:
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return head;
RandomListNode newHead = new RandomListNode(head.label);
HashMap<RandomListNode, RandomListNode> map = new HashMap();
map.put(head, newHead);
RandomListNode p = newHead;
while(head != null) {
if(head.next != null) {
if(map.containsKey(head.next))
p.next = map.get(head.next);
else {
p.next = new RandomListNode(head.next.label);
map.put(head.next, p.next);
}
} else {
p.next = null;
}
if(head.random != null) {
if(map.containsKey(head.random))
p.random = map.get(head.random);
else {
p.random = new RandomListNode(head.random.label);
map.put(head.random, p.random);
}
} else {
p.random = null;
}
head = head.next;
p = p.next;
}
return newHead;
}
}
11 / 11 test cases passed.
Status: Accepted
Runtime: 7 ms
大神第一种解法:
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return head;
HashMap<RandomListNode,RandomListNode> map = new HashMap<RandomListNode,RandomListNode>();
RandomListNode newHead = new RandomListNode(head.label);
map.put(head,newHead);
RandomListNode pre = newHead;
RandomListNode node = head.next;
while(node!=null)
{
RandomListNode newNode = new RandomListNode(node.label);
map.put(node,newNode);
pre.next = newNode;
pre = newNode;
node = node.next;
}
node = head;
RandomListNode copyNode = newHead;
while(node!=null)
{
copyNode.random = map.get(node.random);
copyNode = copyNode.next;
node = node.next;
}
return newHead;
}
}
11 / 11 test cases passed.
Status: Accepted
Runtime: 5 ms
大神第二种解法:
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return head;
RandomListNode node = head;
while(node!=null)
{
RandomListNode newNode = new RandomListNode(node.label);
newNode.next = node.next;
node.next = newNode;
node = newNode.next;
}
node = head;
while(node!=null)
{
if(node.random != null)
node.next.random = node.random.next;
node = node.next.next;
}
RandomListNode newHead = head.next;
node = head;
while(node != null)
{
RandomListNode newNode = node.next;
node.next = newNode.next;
if(newNode.next!=null)
newNode.next = newNode.next.next;
node = node.next;
}
return newHead;
}
}
11 / 11 test cases passed.
Status: Accepted
Runtime: 2 ms