题目大意:复制一个具有随机指针的链表。也就是说一个单链表中的每一个节点除了有next域之外还有一个random域,这个域指向这个单链表中的任意一个节点,当然也可以不指向任何节点,让你复制这个链表。
思路分析:遍历第一遍先将单链表复制出来,第二遍遍历时再更新random域,在第一遍遍历的过程当中保存旧链表节点和新链表节点之间的映射关系,以旧链表的节点为key,以相对应的新链表节点为value。
代码如下:
/**
* 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) {
RandomListNode oldCurrent, newCurrent, newHead, tmpNode;
if(head==null) {
return null;
}
oldCurrent = head;
Map<RandomListNode, RandomListNode> oldNode2newNodeMap = new HashMap<RandomListNode, RandomListNode>();
newHead = new RandomListNode(oldCurrent.label);
newCurrent = newHead;
oldNode2newNodeMap.put(oldCurrent, newCurrent);
oldCurrent = oldCurrent.next;
while(oldCurrent!=null) {
tmpNode = new RandomListNode(oldCurrent.label);
newCurrent.next = tmpNode;
newCurrent = tmpNode;
oldNode2newNodeMap.put(oldCurrent, newCurrent);
oldCurrent = oldCurrent.next;
}
oldCurrent = head;
newCurrent = newHead;
while(oldCurrent!=null) {
if(oldCurrent.random!=null) {
newCurrent.random = oldNode2newNodeMap.get(oldCurrent.random);
}
else {
newCurrent.random = null;
}
oldCurrent = oldCurrent.next;
newCurrent = newCurrent.next;
}
return newHead;
}
}
思路比较清晰,但是代码略显繁杂,还有一种思路可以简化一下。那就是不管什么单链表不单链表,第一遍遍历的时候只把那些节点建立出来,并且同样建立map映射关系,在第二遍遍历的时候才更新next域和random域。