題目:請實現一個函數,複製一個複雜鏈表。node
在複雜鏈表中,每一個結點除了有一個next指針指向下一個結點外,還有一個sibling指針指向鏈表中的任意結點或者nulL算法
直觀解法:app
1.遍歷鏈表,複製鏈表節點,並鏈接next節點。2.遍歷鏈表,鏈接sibling節點。對於一個有n個節點的鏈表,因爲定位每一個節點的silbing節點都須要從鏈表的頭結點開始通過O(n)步才能實現,所以這種方法的時間複雜度是O(n2)函數
優化解法:上述方法的時間主要是用在了sibling節點的定位上,考慮優化此步驟。具體的作法是在複製節點的時候,把原節點N和複製出來的N'節點用一個map保存起來,這樣在第二部鏈接sibling結點的時候就能夠以O(1)的時間複雜度定位到相應的sibling節點,整體時間複雜度爲O(n),空間複雜度也是O(n)優化
最優算法:ui
第一步:根據原始鏈表的每一個節點建立對應的複製結點,把複製結點鏈接在原結點的後面
第二步:設置複製出來的結點的任意結點sibling節點
第三步:把長鏈表拆分紅兩個鏈表
this
1 package Solution; 2 3 public class No26CopyComplexList { 4 5 static class ComplexListNode{ 6 int value; 7 ComplexListNode next; 8 ComplexListNode sibling; 9 public ComplexListNode(){ 10 11 } 12 public ComplexListNode(int value,ComplexListNode next,ComplexListNode sibling){ 13 this.value=value; 14 this.next=next; 15 this.sibling=sibling; 16 } 17 } 18 19 //把複雜鏈表中的全部結點進行復制,並鏈接在原結點的後面 20 private static void cloneNode(ComplexListNode head){ 21 ComplexListNode node=head; 22 while(node!=null){ 23 ComplexListNode clonedNode=new ComplexListNode(); 24 clonedNode.value=node.value; 25 clonedNode.next=node.next; 26 clonedNode.sibling=null; 27 node.next=clonedNode; 28 node=clonedNode.next; 29 } 30 } 31 //設置複製的節點的指向任意結點的鏈接關係 32 private static void connectSiblingNodes(ComplexListNode head){ 33 ComplexListNode node=head; 34 while(node!=null){ 35 ComplexListNode clonedNode=node.next; 36 if(node.sibling!=null){ 37 clonedNode.sibling=node.sibling.next; 38 } 39 node=clonedNode.next; 40 } 41 } 42 //把長鏈表拆分紅兩個單獨的鏈表,並返回複製後的鏈表的頭結點 43 private static ComplexListNode reconnectNodes(ComplexListNode head){ 44 ComplexListNode node=head; 45 ComplexListNode clonedHead=null; 46 ComplexListNode clonedNode=null; 47 if(node!=null){ 48 clonedHead=clonedNode=node.next; 49 node.next=clonedNode.next; 50 node=clonedNode.next; 51 } 52 while(node!=null){ 53 clonedNode.next=node.next; 54 clonedNode=node.next; 55 node.next=clonedNode.next; 56 node=clonedNode.next; 57 } 58 return clonedHead; 59 } 60 public static ComplexListNode copyComplexList(ComplexListNode head){ 61 if(head==null) 62 return null; 63 cloneNode(head); 64 connectSiblingNodes(head); 65 return reconnectNodes(head); 66 } 67 68 public static void printComplexList(ComplexListNode head){ 69 ComplexListNode node=head; 70 int value=0; 71 ComplexListNode next=null; 72 ComplexListNode sibling=null; 73 while(node!=null){ 74 value=node.value; 75 next=node.next; 76 sibling=node.sibling; 77 StringBuilder sb=new StringBuilder("當前節點的值爲:").append(value); 78 if(next!=null) 79 sb.append(",下一結點的值爲:").append(next.value); 80 else 81 sb.append(",當前結點爲尾節點"); 82 if(sibling!=null) 83 sb.append(",指向任意結點的值爲:").append(sibling.value); 84 else 85 sb.append(",沒有指向其餘結點的任意結點"); 86 System.out.println(sb.toString()); 87 node=node.next; 88 } 89 } 90 public static void main(String[] args) { 91 ComplexListNode node1=new ComplexListNode(); 92 ComplexListNode node2=new ComplexListNode(); 93 ComplexListNode node3=new ComplexListNode(); 94 ComplexListNode node4=new ComplexListNode(); 95 ComplexListNode node5=new ComplexListNode(); 96 node1.value=1; 97 node1.next=node2; 98 node1.sibling=node3; 99 node2.value=2; 100 node2.next=node3; 101 node2.sibling=node5; 102 node3.value=3; 103 node3.next=node4; 104 node3.sibling=null; 105 node4.value=4; 106 node4.next=node5; 107 node4.sibling=node2; 108 node5.value=5; 109 node5.next=null; 110 node5.sibling=null; 111 printComplexList(node1); 112 System.out.println("=========================開始複製============================"); 113 printComplexList(copyComplexList(node1)); 114 } 115 }