Q35複雑なリンクリストの複製

複雑なリンクリストの複製

タイトル

複雑なリンクリストを入力します(各ノードにはノード値があり、2つのポインターがあり、1つは次のノードを指し、別の特別なポインターは任意のノードを指します)。返される結果は、コピー後に複雑なリンクリストの先頭になります。(出力結果のパラメーターにノード参照を返さないでください。そうしないと、判定プログラムが直接空を返します)

アイデア

アイデア1:

  1. 通常どおりコピー
  2. コピー後、ポインターは最初のリンクリストを指し、ポインターは2番目のリンクリストを指します。同時に先に進み、ランダムポインターが指すノードを特定し、ポイントを完了します。ランダムポインタが指す各ノードは、リンクリストの全探索を必要とします。
  3. 全体的な複雑さは 2 O(n ^ 2)

アイデア2:

  1. リンクリストをコピーしますが、コピーしたノードは元のリンクリストの各ノードの後ろに配置します。以前はnノードでしたが、現在は2nです。
  2. 複製後に各ノードのランダムによってポイントされるノードは、元のリンクリストの各ノードによってポイントされるノードの次のノードです。
    下の図を見ると、AがCをポイントしていると仮定すると、A1はCの次のC1をポイントします。
  3. 2nノードを2つのリンクリストに分割します。

元のリンクリスト:

A
B
C
D

コピー後:

A
A1
B
B1
C
C1
D
D1

ランダムポインターのあるスケマティックダイアグラム:

A
A1
B
B1
C
C1
D
D1

達成する

アイデア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;
    }
};
元の記事を58件公開 11 件を獲得 30,000回以上の閲覧

おすすめ

転載: blog.csdn.net/mhywoniu/article/details/105606077