M1: 复制带随机指针的链表
题目:有一个链表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 + ")]"; } }