劍指offer——複雜連結串列的複製C++
阿新 • • 發佈:2020-12-27
技術標籤:劍指Offer#連結串列指標連結串列單鏈表演算法劍指offer
預設所有結點的random指標不會指向不在連結串列中的獨立結點。
兩種方法:遞迴和迴圈
遞迴:需要通過一個輔助的map來實現,這個map是用來處理random指標指向的結點的,防止重複新建node。在遞迴函式中根據當前結點的值new一個結點指標,在map記錄當前指標對應的指標是新建的這個。然後遞迴next結點。當next都遞迴完後,判斷當前結點的random是否為空,如果不為空,就將新建的這個結點的random指向map儲存的原結點的random指標的拷貝指標。最後返回新建的指標即可。
迴圈:三步法,每一步都不簡單,每一步都有細節,好處就是不用O(N)空間複雜度的map
2.連線random域,A1.random = A.random.next
3.拆分單鏈表,改變A1的next為A的next的next
定義一個currentnode來指向當前遍歷到的結點,初始賦值為pHead
第一步:當currentnode為空時結束迴圈,根據currennode來new一個克隆結點,並且定義一個nextnode來儲存當前結點的下一個結點(防止等下改變next後找不到後序的結點)。將當前結點的next改為克隆結點,將克隆結點的next改為nextnode,currentnode=nextnode。
第二步:將currentnode重新指向pHead,重新回到這條鏈的起點處。這次currentnode指的全是原先連結串列中的結點,不是克隆結點,所以跳著訪問。找原連結串列上的所有結點random指標是否為空,如果不為空,就將當前結點的random指標的next賦給當前結點的拷貝(也就是當前結點的next)的random。最後使currentnode指向它next的next。
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
//map<RandomListNode*,RandomListNode*> ma;
RandomListNode* Clone(RandomListNode* pHead)
{
//首先我們要知道所有random結點都是在這條連結串列裡的,不存在一個獨立結點被random指到
//所有random結點都能被next指到
//所以先遞迴複製所有next指標指向的結點,並將其存入ma中,可以通過原結點找到深拷貝的結點
//每一輪遞迴複製完next後,從ma中拿出原結點的random復給現在結點的random
/*if(pHead == NULL) return NULL;
RandomListNode* node = new RandomListNode(pHead->label);
ma[pHead] = node;
node->next = Clone(pHead->next);
node->random = NULL;
if(pHead->random) node->random = ma[pHead->random];
return node;*/
//法2:三步法,通過next指標關聯,不用輔助map
//複製單鏈表,將A1插入到A後面,A2前面
//連線random域,A1.random = A.random.next
//拆分單鏈表,改變A1的next為A的next的next
if(pHead == NULL) return NULL;
RandomListNode* currentNode = pHead;
while(currentNode != NULL){
RandomListNode* cloneNode = new RandomListNode(currentNode->label);
RandomListNode* nextNode = currentNode->next;
currentNode->next = cloneNode;
cloneNode->next = nextNode;
currentNode = nextNode;
}
currentNode = pHead;
while(currentNode != NULL){
//這個判斷必須加!
if(currentNode->random != NULL){//如果原結點random指標不為空
//那麼複製的結點的random就指向原結點的random的複製結點
currentNode->next->random = currentNode->random->next;
}
currentNode = currentNode->next->next;
}
currentNode = pHead;
RandomListNode* pCloneHead = pHead->next;
while(currentNode != NULL){
RandomListNode* cloneNode = currentNode->next;
currentNode->next = cloneNode->next;
cloneNode->next = cloneNode->next == NULL ? NULL : cloneNode->next->next;
currentNode = currentNode->next;
}
return pCloneHead;
}
};