zoukankan      html  css  js  c++  java
  • 复杂链表的复制

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

    结点结构体如下:

    /*
    struct RandomListNode {
        int label;
        struct RandomListNode *next, *random;
        RandomListNode(int x) :
                label(x), next(NULL), random(NULL) {
        }
    };
    */

    这是一道剑指offer上的题目。下面看一下解析吧。

    在做这道题之前,自己的想法是先把链表中的next域全部复制,这时候原复杂链表的random域的所有指向都会存在于刚才复制的链表中,之后再遍历原复杂链表,将新链表random域与原链表random域相互对应即可。

    但是过程中问题就出现了,虽然我可以在将原链表的所有next域全部复制,也保证了即将要复制的random域的指向存在于该链表中,但是random域是随机指的,也就是说并不知道当前的random域指向的结点在前面还是后面,如此一来,如果还要继续下去,恐怕还要嵌套一层循环。

    为此,又在网上找了大神的博客参考下,真的是受益匪浅。

    想想我们平时复制粘贴一段文字的时候是怎么做的?是照着那段文字一个一个的再敲一次吗?并不是,很显然,我们是直接在该段文字上复制,然后将复制后的文字粘贴到我们想要的地方。

    上面的笨办法显然就是一个一个的再敲一个链表出来,并没有做真正的复制

    那怎么做?对,就是直接在原链表上复制一份链表,最后将我们想要的备份链表从原链表中抽离出来。

    具体分三个步骤:

    1.再原链表的每个结点后面插入一个与当前结点数据域相同的结点

    2.复制random域的对应关系

    3.抽离链表

    完整代码如下

        RandomListNode* Clone(RandomListNode* pHead)
        {
            if(!pHead){
                return NULL;
            }
            RandomListNode *head = NULL;
            RandomListNode *p, *pf = NULL;
            RandomListNode *q;
    // 先复制结点
            for(p = pHead; p; p = p->next->next){
                q = new RandomListNode(p->label);
                q->next = p->next;
                p->next = q;
            }
    // 复制random域对应关系
            for(p = pHead; p; p = p->next->next){
                if(!p->random){
                    p->next->random = p->random;
                }else{
                    p->next->random = p->random->next;
                }
            }
    //抽离链表
            head = pHead->next;
            for(p = pHead, q = head; q; q = q->next){
                p->next = p->next->next;
                if(q->next){
                   p = p->next;
                   q->next = q->next->next; 
                }
            }
            return head;
        }

    下面附一下参考链接,上面有图,更容易理解。

    https://blog.csdn.net/H_Strong/article/details/83042934

    end。

  • 相关阅读:
    动态规划——Best Time to Buy and Sell Stock IV
    动态规划——Split Array Largest Sum
    动态规划——Burst Ballons
    动态规划——Best Time to Buy and Sell Stock III
    动态规划——Edit Distance
    动态规划——Longest Valid Parentheses
    动态规划——Valid Permutations for DI Sequence
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/GuoYuying/p/11478469.html
Copyright © 2011-2022 走看看