【Java】 劍指offer(35) 複雜鏈表的複製

本文參考自《劍指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)指針

Java代碼

//題目:請實現函數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),能夠考慮使用哈希表。哈希表的應用要掌握。

 

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索