zoukankan      html  css  js  c++  java
  • 剑指offer 26:复杂链表的复制

      

    题目描述

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

    解题思路

    对此问题,每个指针节点存在两个链域,一个指向下一节点,另一个指向任意节点。首要需要完成的是对节点进行复制,然后对复制后的节点间的指向关系进行复制。
    此问题分为三步来解决,时间复杂度为O(n):
    step1:在原节点基础上,对每个节点进行复制,并将复制节点插入被复制节点之后。
    step2:由于复制节点是被复制节点的滞后一个单位位置的点,所以当被复制节点存在一个特殊指针指向某一节点时,复制节点也应执行相同操作,而复制节点特殊指针的指向,一定是被复制节点特殊指针指向节点的下一个节点元素,按此规则对链表中所有节点进行遍历,完成特殊指针指向复制。
    setp3:将原链表与复制链表分离,由于原链表与复制链表的元素交叉相连,所以直接按照交替顺序遍历就可实现两个链表的分离。
    C++代码实现如下:
    /*
    struct RandomListNode {
        int label;
        struct RandomListNode *next, *random;
        RandomListNode(int x) :
                label(x), next(NULL), random(NULL) {
        }
    };
    */
    class Solution {
    public:
        RandomListNode* Clone(RandomListNode* pHead)
        {
            clone1(pHead);
            clone2(pHead);
            RandomListNode* head= clone3(pHead);
            return head;
        }
        void clone1(RandomListNode* pHead){
            //step1: 逐个复制列表元素,并重新复制一个链表
            
            if(pHead==NULL){
                return;
            }
            RandomListNode* pNode=pHead;
            while(pNode!=NULL){
                
                RandomListNode* newNode=new RandomListNode(pNode->label);
                newNode->next=pNode->next;
                pNode->next=newNode;
                pNode=newNode->next;
            }
        }
        void clone2(RandomListNode* pHead){
            //step2:设置随机指针的指向
            if(pHead==NULL){
                return;
            }
            RandomListNode* pNode=pHead;
            while(pNode!=NULL){
                RandomListNode* pNode2=pNode->next;
                if(pNode->random!=NULL){
                    pNode2->random=pNode->random->next;    
                }
                pNode=pNode2->next;
            }
        }
        RandomListNode* clone3(RandomListNode* pHead){
            if(pHead==NULL){
                return NULL;
            }
            RandomListNode* pNode1=pHead;
            RandomListNode* Head2=pNode1->next;
            RandomListNode* pNode2=pNode1->next;
            pNode1->next=pNode2->next;
            pNode1=pNode1->next;
            while(pNode1!=NULL){
                pNode2->next=pNode1->next;
                pNode2=pNode2->next;
                pNode1->next=pNode2->next;
                pNode1=pNode1->next;
            }
            return Head2;
        }
    };
  • 相关阅读:
    实现centos系统的自动化安装部署
    加密与CA证书的创建
    Linux系统启动和内核管理
    进程,系统性能和计划任务
    第十七周运维作业
    第十六周运维作业
    第十四周运维作业
    第十三周运维作业
    第十二周运维作业
    第十一周运维作业
  • 原文地址:https://www.cnblogs.com/fancy-li/p/11723089.html
Copyright © 2011-2022 走看看