問題描述:
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點)。
思路1:
1.先複製鏈表節點,並用next鏈接起來。
2.然後對每一個結點去修改它的隨機指針S。遍歷鏈表找到S。
時間複雜度O(n^2)
思路2:
1.先複製鏈表節點N-N’,並用next鏈接起來,並用一個哈系表存儲《N, N‘》結點對,
2.然後對每一個結點去修改它的隨機指針S。此時,我們根據哈系表很容易添加每個複製節點的random指針。
時間複雜度O(n),空間複雜度O(n)
思路3:
在思路2的基礎上,不使用額外的內存空間。
1.複製原始鏈表結點N—-》N’,並把N‘插入到N的後面。
2.那麼原來的隨機指針N-》S ,此刻就應該變爲:N’-S‘,顯然都是很容易獲得的。
3.把上述鏈表拆分成兩個鏈表,一個是原來的鏈表,一個是新複製的鏈表。
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead == null){
return null;
}
//複製接結點
CopyList(pHead);
//連接隨機指針
ConnectRandom(pHead);
//拆分鏈表
return ReconnectNodes(pHead);
}
public static void CopyList(RandomListNode pHead){
if(pHead == null){
return;
}
RandomListNode pNode = pHead;
while(pNode != null){
RandomListNode pCloned = new RandomListNode(pNode.label);
pCloned.next = pNode.next;
pCloned.random = null;
pNode.next = pCloned;
pNode = pCloned.next;
}
}
public static void ConnectRandom(RandomListNode pHead){
RandomListNode pNode = pHead;
while(pNode != null){
RandomListNode pCloned = pNode.next;
if(pNode.random != null){
pCloned.random = pNode.random.next;
}
pNode = pCloned.next;
}
}
public static RandomListNode ReconnectNodes(RandomListNode pHead){
RandomListNode pNode = pHead;
RandomListNode pClonedHead = null;
RandomListNode pClonedNode = null;
if(pNode != null){
pClonedHead = pClonedNode = pNode.next;
pNode.next = pClonedNode.next;
pNode = pNode.next;
}
while(pNode != null){
pClonedNode.next = pNode.next;
pClonedNode = pClonedNode.next;
pNode.next = pClonedNode.next;
pNode = pNode.next;
}
return pClonedHead;
}
}