原題如下:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
普通單鏈表的複製是比較容易的,此題的難點在於複製後新節點的Random指針的指向問題,這裏也是參考了一篇大牛的博文的思路http://www.cnblogs.com/TenosDoIt/p/3387000.html,其中第一種方法的空間複雜度爲O(n),第二種方法的空間複雜度爲O(1),所以在此採用第二種方法。實現主要分爲三個步驟:一是根據原節點構建新的節點並將新節點插入對應原節點之後,這需要一次掃描原鏈表;二是根據原節點的Random指針設置新節點的Random指針,這裏Ramdom指針的設置需要分三種不同的情況:random指針爲空、指向自身、指向其他節點,三種情況的處理方法是不同的,另外在涉及將指針指向其後的第三個節點的問題時(如p=p->next->next),一定要首先保證其後的第一個節點是存在的,所以需要對最後一個節點的Random指針進行單獨處理;三是將新鏈表與原鏈表分離,分離時同樣是從前往後掃描鏈表,同時仍然需要對最後一個節點進行單獨處理。class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL )
return NULL;
RandomListNode *p = head,*preP = head,*tHead;
while(p != NULL) //構造新節點並插入原節點的節點尾
{
RandomListNode *node = new RandomListNode(p->label);
node->next = p->next;
p->next = node;
p = node->next;
}
p = head->next;
while(p != NULL && p->next != NULL){ //參照原節點的Random指針設置新節點的Random指針指向
if(preP->random == NULL)
p->random = NULL;
else if(preP->random == preP)
p->random = p;
else
p->random = preP->random->next;
preP = p->next;
p = p->next->next;
}
if(preP->random == NULL) //最後一個節點需單獨處理
p->random = NULL;
else if(preP->random == preP)
p->random = p;
else
p->random = preP->random->next;
tHead = head->next;
preP = head;
p = head->next;
while(p != NULL && p->next != NULL){ //將新鏈表與原鏈表分離
preP->next = p->next;
p->next = p->next->next;
preP = preP ->next;
p = p->next;
}
preP->next = NULL;
return tHead;
}
};
今天覆習這道題時發現不需要對最後的節點做特殊處理,更新後的代碼如下:class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if (head == NULL)
return NULL;
RandomListNode *p = head;
while(p != NULL){
RandomListNode *node = new RandomListNode(p->label);
node->next = p->next;
p->next = node;
p = node->next;
}
p = head;
while(p != NULL){
if(p->random == p)
p->next->random = p->next;
else if(p->random == NULL)
p->next->random = NULL;
else
{
p->next->random = p->random->next;
}
p = p->next->next;
}
RandomListNode *tHead = new RandomListNode(0);
RandomListNode *index = tHead;
p = head;
while(p != NULL)
{
index->next = p->next;
index = p->next;
p->next = index->next;
p = p->next;
}
p = tHead->next;
delete tHead;
return p;
}
};