題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
我的代碼,思路比較笨,就是首先構造一個正常的不大random指針的鏈表,然後再去遍歷原始鏈表,查看random指針指向的位置,同時移動複製的鏈表的next,找到後賦值。時間複雜度比較大O(n^2)
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
RandomListNode head2 = null ;
RandomListNode cur = head2;
RandomListNode tmp = pHead;
while(tmp!=null){
RandomListNode node = new RandomListNode(tmp.label);
if(cur == null)
cur = head2 = node;
else
{
cur.next = node;
cur = node;
}
tmp = tmp.next;
}
cur = head2;
tmp = pHead;
while(cur!=null){
RandomListNode tmp1 = pHead;
RandomListNode tmp2 = head2;
while(tmp.random != tmp1&&tmp1!=null){
tmp1 = tmp1.next;
tmp2 = tmp2.next;
}
tmp = tmp.next;
cur.random = tmp2;
cur = cur.next;
}
return head2;
}
}
優秀代碼,c++寫的,忽略語言,看療效,首先將複製的節點插入到對應的原始節點的後面,這樣組成了一個複製節點和原始節點混合的鏈表,此時鏈表上除了原始鏈表節點上的random有指向外,新生成的節點random均爲空。下一步就是補齊random節點,利用新舊節點混合在一起的優勢,可以很快找到新節點的random指針的指向。最後,沒隔一個拆分開。得到原始節點。時間複雜度O(n)。畫了張圖,將就着看吧。找到紅色的random指向後,綠色的也就很容易找到了。
class Solution {
public:
/*
1、複製每個節點,如:複製節點A得到A1,將A1插入節點A後面
2、遍歷鏈表,A1->random = A->random->next;
3、將鏈表拆分成原鏈表和複製後的鏈表
*/
RandomListNode* Clone(RandomListNode* pHead)
{
if(!pHead) return NULL;
RandomListNode *currNode = pHead;
while(currNode){
RandomListNode *node = new RandomListNode(currNode->label);
node->next = currNode->next;
currNode->next = node;
currNode = node->next;
}
currNode = pHead;
while(currNode){
RandomListNode *node = currNode->next;
if(currNode->random){
node->random = currNode->random->next;
}
currNode = node->next;
}
//拆分
RandomListNode *pCloneHead = pHead->next;
RandomListNode *tmp;
currNode = pHead;
while(currNode->next){
tmp = currNode->next;
currNode->next =tmp->next;
currNode = tmp;
}
return pCloneHead;
}
};