題目描述
輸入乙個複雜鍊錶(每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標random指向乙個隨機節點),請對此鍊錶進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空)
首先第一種想法是分兩步進行,首先複製原始鍊錶的每個節點,通過.next連線起來,然後設定每個節點的random,複雜的就是這一步,因為無法確定random的位置,所以需要從頭節點開始找,對於原始鍊錶的每個節點,找到它的random從頭節點走了多少步,那新鍊錶對應節點的random也需要從頭節點走多少步。這樣就找到了對應的random。這一步每個節點random都需要n步,共n個節點,所以時間複雜度是o(n^2);
由此分析可以看出,我們主要的時間花費在了找random上,所以我們想辦法優化random的查詢,我們在這裡不採用暴力查詢法,使用空間換時間的思路。試想一下,如果我們可以根據原始鍊錶節點的random節點直接定位到新鍊錶的random節點,不是就不需要從頭查詢random節點了麼?
所以辦法就來了,那就是對原始鍊錶的每個節點,都和新鍊錶的每個節點建立一一對應的關係即可,當然我們想到map最合適,這樣就實現了o(1)的時間複雜度。
上**:
public
class
solution
else
} next = next.next;
}while
(!stack.
isempty()
)return nhead.next;
}}
上面的**雖然把時間複雜度降下來了,但是空間複雜度上去了,我們接下來再想想能不能在優化一下空間複雜度呢。優化思路當然就是取消hashmap,也就是說如果不用hashmap,我們該如何通過原節點的random尋找新節點的random呢?
我們可以把新節點都放在對應原始節點的next裡面!!!
這樣就是和hashmap的key-value一樣的道理!!!
只是處理起來複雜一點,具體分三步:
把複製的結點鏈結在原始鍊錶的每一對應結點後面
把複製的結點的random指標指向被複製結點的random指標的下乙個結點
拆分成兩個鍊錶,奇數字置為原鍊錶,偶數字置為複製鍊錶,注意複製鍊錶的最後乙個結點的next指標不能跟原鍊錶指向同乙個空結點none,next指標要重新賦值none(判定程式會認定你沒有完成複製)
根據上面三步,**如下,每個while迴圈完成乙個功能
public
class
solution
randomlistnode currentnode = phead;
//1、複製每個結點,如複製結點a得到a1,將結點a1插到結點a後面;
while
(currentnode != null)
currentnode = phead;
//2、重新遍歷鍊錶,複製老結點的隨機指標給新結點,如a1.random = a.random.next;
while
(currentnode != null)
//3、拆分鍊錶,將鍊錶拆分為原鍊錶和複製後的鍊錶
currentnode = phead;
randomlistnode pclonehead = phead.next;
while
(currentnode != null)
return pclonehead;
}}
劍指offer35題 複雜鍊錶的複製
請實現 copyrandomlist 函式,複製乙個複雜鍊錶。在複雜鍊錶中,每個節點除了有乙個 next 指標指向下乙個節點,還有乙個 random 指標指向鍊錶中的任意節點或者 null。示例 1 輸入 head 7,null 13,0 11,4 10,2 1,0 輸出 7,null 13,0 1...
劍指Offer 35 複雜鍊錶的複製
請實現啊函式complexlistnode clone complexlistnode phead 複製乙個 複雜鍊錶。在複雜鍊錶中除了有乙個m pnext指標指向下乙個節點,還有乙個m psaibling 指標指向鍊錶中的任意節點或者nullptr。節點定義如下 class complexlist...
(劍指offer)35 複雜鍊錶的複製
輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 思路 1.先複製鍊錶節點的值放在原來的節點後面,組成乙個新的鍊錶 2.處理複雜指標 安排複...