题解 | 复杂链表的复制
/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if (pHead == nullptr) return nullptr; RandomListNode* curr = pHead; RandomListNode* orgNext = nullptr; while (curr != nullptr) { orgNext = curr->next; curr->next = new RandomListNode(curr->label); //update the newly added node curr->next->next = orgNext; curr = orgNext; } // update the random node curr = pHead; while (curr != nullptr) { if (curr->random == nullptr) { // the random pointer pointing to nullptr curr->next->random = nullptr; curr = curr->next->next; } else { curr->next->random = curr->random->next; curr = curr->next->next; } } // split the list curr = pHead; orgNext = nullptr; RandomListNode* dupHead = pHead->next; while (curr != nullptr) { orgNext = curr->next; if (orgNext == nullptr) break; curr->next = curr->next->next; curr = orgNext; } return dupHead; // RandomListNode* curr = pHead; // RandomListNode* tmp = nullptr; // // duplicate the node in place // while (curr != nullptr) { // tmp = curr; // RandomListNode* dupNode = new RandomListNode(tmp->label); // curr->next = dupNode; // dupNode->next = tmp->next;; // curr = dupNode->next; // } // // add random link // curr = pHead; // RandomListNode* cpyHead = pHead->next; // // RandomListNode* tmpRand = cpyHead; // // while (tmpRand->next != nullptr) { // // tmpRand->random = curr->random->next; // // tmpRand = tmpRand->next->next; // // curr = curr->next->next; // // } // tmp = cpyHead; // while (tmp->next != nullptr) { // tmp->random = curr->random->next; // tmp = tmp->next->next; // curr = curr->next->next; // } // // separate the structure // // tmp = pHead; // // RandomListNode* tmpCpy = cpyHead; // RandomListNode* prev = nullptr; // // curr = cpyHead; // curr = pHead->next; // while (curr->next != nullptr) { // prev = curr->next; // curr->next = curr->next->next; // curr = prev->next; // } // // RandomListNode* orgNext = nullptr; // // RandomListNode* cpyNext = nullptr; // // RandomListNode* interimOrgNext = nullptr; // // RandomListNode* interimCpyNext = nullptr; // // while (tmpCpy->next != nullptr) { // // orgNext = tmpCpy->next; // // cpyNext = orgNext->next; // // interimOrgNext = tmp->next->next; // // interimCpyNext = tmpCpy->next->next; // // tmp->next = orgNext; // // tmpCpy->next = cpyNext; // // tmp = interimOrgNext; // // tmpCpy = interimCpyNext; // // } // return cpyHead; } };
不能直接的去创建单独的一个新的复制好的链表,因为这里还有Random指针,在直接创建好之后再想去找到原来Random所指向的对象就很困难了(区别于找到相同的label值,这里我们并不关注label的值,更关注的其实是链表的结构
我们通过in place的方式去duplicate链表,扩展原来的链表元素,这一步的目的是服务于刚刚random指针无法定位的情况。现在就可以通过next的指针去寻找对应的random指向的对象,根据原来的链表情况。
补充好random指针后最后一步是拆分链表,这一步的时候同样需要双指针,比较容易