复杂链表的复制(Hard)
问题来源:选自LeetCode 138:复制带随机指针的链表
问题描述:
题目给定信息:
该链表中每一个节点的成员变量都有两个,一个是next指针指向该节点的下一个节点,一个是random指针指向不确定,可以指向该链表中任意一个节点,也可以指向它自己,还可以指向为空,我们要克隆这个链表,并且保证每一个链表节点的两个指针都和原链表是一样的。
问题分析:
我们可以间接的利用节点地址和节点序号之间的映射关系,在Map集合中存贮两个链表(原链表和新建待克隆链表)的映射关系。通过一个while循环,创建出和每个链表节点值相同的节点,并且把这些节点都按照映射关系存进Map集合中,在这个循环中还能把新创建的节点的next指针赋上相应的值。然后再经过一个while循环,每遍历到原链表的一个节点,我们就在Map集合中找到该节点映射对应的新创建节点是哪一个,这样就能给新创建的节点的random指针进行赋值操作,便利循环结束,新创建的每一个节点的random指针也全部赋值结束。返回新创建的链表头指针就可以了。
函数实现:
方法一:
1 public Node copyRandomList(Node head) { 2 if (head == null) { 3 return null; 4 } 5 Node newHead = new Node(head.val, null, null); 6 Node temp = head.next; 7 Node temp_New = newHead; 8 Map<Node, Node> map = new HashMap<>(); 9 map.put(head, newHead); 10 while (temp != null) { 11 Node newList = new Node(temp.val, null, null); 12 map.put(temp, newList); 13 temp_New.next = newList; 14 temp_New = newList; 15 temp = temp.next; 16 } 17 temp = head; 18 temp_New = newHead; 19 while (temp != null) { 20 temp_New.random = map.get(temp.random); 21 temp = temp.next; 22 temp_New = temp_New.next; 23 } 24 return newHead; 25 }
方法二:
1 public Node copyRandomList(Node head) { 2 Map<Node, Integer> map = new HashMap<Node, Integer>(); 3 Vector<Node> vector = new Vector<Node>(); 4 Node node = head; 5 int i = 0; 6 while (node != null) { 7 vector.add(new Node(node.val, null, null)); 8 map.put(node, i); 9 node = node.next; 10 i++; 11 } 12 node=head; 13 i=0; 14 while(node!=null){ 15 vector.get(i).next=vector.get(i+1); 16 if(node.random!=null){ 17 int id=map.get(node); 18 vector.get(i).random=vector.get(id); 19 } 20 node=node.next; 21 i++; 22 } 23 return vector.get(0); 24 }
运行结果: