本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
請實現函數ComplexListNode* Clone(ComplexListNode* pHead),複製一個複雜鏈表。在複雜鏈表中,每一個結點除了有一個m_pNext指針指向下一個點外,還有一個m_pSibling 指向鏈表中的任意結點或者nullptr。函數
思路1:先複製結點,用next連接,最後根據原始結點的sibling指針肯定該sibling結點距離頭結點的位置,從而對複製結點設置sibling指針。可是該思路對於n個結點的鏈表,每一個結點的sibling都須要O(n)個時間步才能找到,因此時間複雜度爲O(n^2)post
思路2:複製原始結點N建立N’,用next連接。將<N,N'>的配對信息存放入一個哈希表中;在設置sibling時,經過哈希表,只須要用O(1)的時間便可找到複製結點的sibling。該方法的時間複雜度爲O(n),但空間複雜度爲O(n)。測試
思路3:複製原始結點N建立N’,將N'連接到N的後面;根據原始結點N的sibling能夠快速設置N'結點的sibling,最後將這個長鏈表拆分紅原始鏈表和複製鏈表(根據奇偶位置)this
測試算例 url
1.功能測試(sibling指向本身;鏈表只有一個結點;sibling指向null或者指向結點)spa
2.特殊測試(頭結點爲null)指針
//題目:請實現函數ComplexListNode* Clone(ComplexListNode* pHead),復 //制一個複雜鏈表。在複雜鏈表中,每一個結點除了有一個m_pNext指針指向下一個 //結點外,還有一個m_pSibling 指向鏈表中的任意結點或者nullptr。 public class CopyComplexList { public class ComplexListNode { int val; ComplexListNode next = null; ComplexListNode sibling = null; ComplexListNode(int label) { this.val = label; } } /* * 主程序(包含三步) */ public ComplexListNode cloneList(ComplexListNode head) { cloneNodes(head); //1.複製結點 connectSiblingNodes(head); //2.設置sibling return reconnectNodes(head);//3.拆分長鏈表 } /* * 第一步:複製每一個結點,並插入到原始節點的後面 */ private void cloneNodes(ComplexListNode head) { ComplexListNode pNode=head; while(pNode!=null) { ComplexListNode clonedNode=new ComplexListNode(pNode.val); clonedNode.next=pNode.next; pNode.next=clonedNode; pNode=clonedNode.next; } } /* * 第二步:根據原結點的sibling,設置複製結點的sibling */ private void connectSiblingNodes(ComplexListNode head) { ComplexListNode pNode=head; while(pNode!=null) { if(pNode.sibling!=null) //必須考慮到siblingNode==null的狀況! pNode.next.sibling=pNode.sibling.next; pNode=pNode.next.next; } } /* * 第三步:將長鏈表拆分紅原始鏈表和複製鏈表(根據奇偶位置) */ private ComplexListNode reconnectNodes(ComplexListNode head) { ComplexListNode clonedHead=null; ComplexListNode clonedNode=null; ComplexListNode pNode=head; if(head!=null) { clonedHead=head.next; clonedNode=pNode.next; pNode.next=clonedNode.next; pNode=pNode.next; //提早將pNode指向下一個結點,方便判斷是否爲null } while(pNode!=null) { clonedNode.next=pNode.next; clonedNode=clonedNode.next; pNode.next=clonedNode.next; pNode=pNode.next; } return clonedHead; } }
1.涉及鏈表結點操做,必須時刻注意對null的判斷htm
2.複製鏈表時,在原始結點後面直接插入複製結點,這種方法很是方便,有較高的時間效率,先記住,之後可能會遇到相似的應用
3.查找時間複雜度爲O(1),能夠考慮使用哈希表。哈希表的應用要掌握。