複雑なリンクリストの複製
記事ディレクトリ
タイトル
複雑なリンクリストを入力します(各ノードにはノード値があり、2つのポインターがあり、1つは次のノードを指し、別の特別なポインターは任意のノードを指します)。返される結果は、コピー後に複雑なリンクリストの先頭になります。(出力結果のパラメーターにノード参照を返さないでください。そうしないと、判定プログラムが直接空を返します)
アイデア
アイデア1:
- 通常どおりコピー
- コピー後、ポインターは最初のリンクリストを指し、ポインターは2番目のリンクリストを指します。同時に先に進み、ランダムポインターが指すノードを特定し、ポイントを完了します。ランダムポインタが指す各ノードは、リンクリストの全探索を必要とします。
- 全体的な複雑さは
アイデア2:
- リンクリストをコピーしますが、コピーしたノードは元のリンクリストの各ノードの後ろに配置します。以前はnノードでしたが、現在は2nです。
- 複製後に各ノードのランダムによってポイントされるノードは、元のリンクリストの各ノードによってポイントされるノードの次のノードです。
下の図を見ると、AがCをポイントしていると仮定すると、A1はCの次のC1をポイントします。 - 2nノードを2つのリンクリストに分割します。
元のリンクリスト:
コピー後:
ランダムポインターのあるスケマティックダイアグラム:
達成する
アイデア2の実装:
/*
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* p1 = pHead;
while(p1!=nullptr)
{ //1. 将链表一个个复制,每复制一个,放到当前节点后面。 原 n个节点,现在2n个
RandomListNode* p1Next = p1->next;
RandomListNode* copyNode = new RandomListNode(p1->label);
p1->next = copyNode;
copyNode->next = p1Next;
p1 = p1Next;
}
p1 = pHead;
while(p1!=nullptr)
{
RandomListNode* pCopied = p1->next;
RandomListNode* pOriginNext = p1->next->next;
if(p1->random!=nullptr)
{//2.复制后的每个节点的random指向的节点,就是原链表每个节点random指向的节点的next。
pCopied->random = p1->random->next;
}
p1 = pOriginNext;
}
//3.拆分成两个链表
p1 = pHead;
RandomListNode* pCopyHead = p1->next;
RandomListNode* p2 = pCopyHead;
while(p1!=nullptr)
{
RandomListNode* pOriginNext = p1->next->next;
RandomListNode* p2next = nullptr;
if(pOriginNext!=nullptr)
p2next = pOriginNext->next;
p1->next = pOriginNext;
p2->next = p2next;
p1 = pOriginNext;
p2 = p2next;
}
return pCopyHead;
}
};
アイデア1の実装:
入力が妥当かどうかを判断することを忘れないでください!!!
/*
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* pCloneHead = new RandomListNode(pHead->label);
RandomListNode* p1 = pHead;
RandomListNode* p2 = pCloneHead;
while(p1->next!=nullptr)
{
p1 = p1->next;
RandomListNode* node = new RandomListNode(p1->label);
p2->next = node;
p2 = node;
}
p1 = pHead;
p2 = pCloneHead;
while(p1!=nullptr)
{
RandomListNode* rd1 = p1->random;
if(rd1!=nullptr){
RandomListNode* pTmp = pHead;
RandomListNode* pTmp2 = pCloneHead;
while(pTmp!=nullptr){
if(pTmp == rd1)
break;
pTmp = pTmp->next;
pTmp2 = pTmp2->next;
}
p2->random = pTmp2;
}
p1 = p1->next;
p2 = p2->next;
}
return pCloneHead;
}
};