题目:有一个链表L,其每个节点有2个指针,一个指针next指向链表的下个节点,另一个random随机指向链表中的任一个节点,可能是自己或者为空,写一个程序,要求复制这个链表的结构并分析其复杂性
解决方法一:
O(n)的复杂度,扫面两边即可。
图【1】
图【1】是需要复制的链表
图【2】
如图【2】所示,ABCD是原来的链表,A’B’C’D’是复制的链表,第一遍扫描顺序复制next指针,把ABCD的next分别指向A’B’C’D’,将A’的next指针指向B,B’的next指针指向C,依次类推
复制random指针: A’->random=A->random->next
恢复:A->next=A’->next;A’->next=A’->next->next;
package careercup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class RandomList {
public static RandomList single = new RandomList();
public RandomList() {
}
public static void main(String[] args) {
int[] arr = new int[]{1,3,5,7};
RandomNode head = RandomNode.createList(arr);
head.randomNext = (RandomNode)head.next.next;
((RandomNode)head.next).randomNext = (RandomNode)head.next.next.next;
RandomNode rn = single.getList(head);
printList(rn);
//printList(head);
}
private static void printList(RandomNode rn) {
while(rn!=null){
System.out.print(rn);
System.out.print(", ");
rn = (RandomNode)rn.next;
}
}
public RandomNode getList(RandomNode rn) {
RandomNode head = rn;
RandomNode p=null;
while(rn!=null){
p = new RandomNode(rn);
p.next = rn.next;
rn.next = p;
rn = (RandomNode)p.next;
}
p = (RandomNode)head.next;
while(p!=null){
p.randomNext = p.randomNext!=null ? (RandomNode)p.randomNext.next : null;
if(p.next!=null) p = (RandomNode)p.next.next;
else break;
}
rn = head;
head = (RandomNode)head.next;
p = head;
rn.next = p.next;
while(rn.next!=null){
p.next = (RandomNode)p.next.next;
p = (RandomNode)p.next;
rn.next = p.next;
}
return head;
}
}
class RandomNode extends Node{
RandomNode randomNext;
RandomNode(int val) {
super(val);
randomNext = null;
}
RandomNode(RandomNode rn){
super(rn.val);
this.next = rn.next;
this.randomNext = rn.randomNext;
}
public static RandomNode createList(int[] arr) {
RandomNode head = new RandomNode(arr[0]);
RandomNode p = head;
for(int i=1; i<arr.length;i++){
p.next = new RandomNode(arr[i]);
p = (RandomNode)p.next;
}
return head;
}
public String toString(){
return "[" + val + "(" + randomNext + ")]";
}
}