• 【剑指Offer-分解让复杂问题简单化】面试题35:复杂链表的复制


    题目描述

    输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

    思路

    可以将该问题的求解分为3步:
    1、对于原始链表中的每个节点复制该节点放在原节点的后面,如下图

    2、设置复制节点的下一个节点。如果原节点N随机指向的节点为S,则N'随机指向的节点为S->next,如下图

    3、经过前两步的链表包含了原始节点和复制的节点,这一步将它们分离:原始链表中的节点下标为奇数(下标从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;
            
            /*1、添加复制后的节点*/
            RandomListNode* curNode = pHead;
            while(curNode!=nullptr)
            {
                RandomListNode* clonedNode = new RandomListNode(curNode->label);
                RandomListNode* nextNode = curNode->next;
                curNode->next = clonedNode;
                clonedNode->next = nextNode;
                curNode = nextNode;
            }
            
            /*2、连接随机节点*/
            curNode = pHead;
            while(curNode!=nullptr)
            {
                RandomListNode* clonedNode = curNode->next;
                if(curNode->random!=nullptr)
                    clonedNode->random = curNode->random->next;
                curNode = clonedNode->next;
            }
            
            /*3、分离原始链表和复制后的链表*/
            RandomListNode* curRaw = pHead;    //原始链表的头结点
            RandomListNode* clonedHead = pHead->next;    //复制的链表的头结点
            RandomListNode* curCloned = clonedHead;
            /*while(curRaw!=nullptr)    //该方法也可以通过
            {
                curCloned = curRaw->next;
                curRaw->next = curCloned->next;
                if(curCloned->next!=nullptr)
                    curCloned->next = curCloned->next->next;
                curRaw = curRaw->next;
            }*/
            
            while(curCloned->next!=nullptr)   //注意终止条件
            {
                curRaw->next = curRaw->next->next;
                curRaw = curRaw->next;
                curCloned->next = curCloned->next->next;
                curCloned = curCloned->next;
            }
            curRaw->next = nullptr;    //使用上面的循环一定要加上这一句,使用注释的循环不需要加
            return clonedHead;
        }
    };
    
  • 相关阅读:
    植物园偶遇一直喵
    植物园偶遇一直喵
    美食篇
    美食篇
    端午节路过南站
    端午节路过南站
    黄山云海
    黄山云海
    Android (1)
    树和树算法(1)
  • 原文地址:https://www.cnblogs.com/flix/p/12470417.html
Copyright © 2020-2023  润新知