zoukankan      html  css  js  c++  java
  • [LeetCode] Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

    Return a deep copy of the list.

    以下是LeetCode Discuss里的思想与代码,很好!

    代码思路:

    • the first loop inserts newly copied node into the original linked list right after the node being copied. E.g., originally (node 0) -> (node 1) -> ...; after the loop, it becomes (node 0) -> (node 0 copy) -> (node 1) -> (node 1 copy) -> ...
    • after the first loop, we know random pointers (p^) for the copied nodes (n^) should point to the immediate following nodes of those (p) being pointed by the nodes being copied (n). take the example above, if the random pointer of (node 0) points at (node 1), then the random pointer of (node 0 copy) points at the immediate following node of (node 1), namely (node 1 copy). this is what the second loop does
    • collect copied nodes and reset the original list back

    代码:

    /**
     * Definition for singly-linked list with a random pointer.
     * struct RandomListNode {
     *     int label;
     *     RandomListNode *next, *random;
     *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     * };
     */
     class Solution{
    public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head == NULL) return NULL;
        RandomListNode *p = head;
        do {
            RandomListNode *q = p->next;
            p->next = new RandomListNode(p->label);
            p->next->next = q;
            p = q;
        } while(p != NULL);
        p = head;
        do {
            p->next->random = (p->random == NULL) ? NULL : p->random->next;
            p = p->next->next;
        } while(p != NULL);
        p = head;
        RandomListNode *r = head->next;
        for(RandomListNode *q = r;;) {
            p->next = q->next;
            p = p->next;
            if(p == NULL) break;
            q->next = p->next;
            q = q->next;
        }
        return r;
    }
    };

    另外一种Dicuss里的方法:
    思路:

    1.依次创建新的结点(next 和 label赋值),并将原来的结点的label改变为编号0、1、2、3....

    2.将创建的新结点存在数组中

    3.按原结点改变的label编号和新结点在数组中的位置,给新结点的random赋值

    4.将原结点的label变回原样

    代码如下:

     RandomListNode *copyRandomList(RandomListNode *head) 
     {
        if(head == NULL)
            return NULL;
        int i,len = 1;
        RandomListNode *p = head->next,**r_pointer,*r_head = NULL,*r_tail = NULL;
        r_head = new RandomListNode(head->label);
        r_tail = r_head;
        head->label = 0;
    
        while(p != NULL){//创建新的结点(next 和 label赋值),将原来的结点的label改变为编号0、1、2、3....
           r_tail->next = new RandomListNode(p->label);
           r_tail = r_tail->next;
           p->label = len;
           p = p->next;
           len++;
        }
    
        r_pointer = new RandomListNode* [len];
        r_tail = r_head;
        i = 0;
        while(r_tail != NULL){//将创建的新结点存在数组中
           r_pointer[i] = r_tail;
           i++;
           r_tail = r_tail->next;
        }
    
        r_tail = r_head;
        p = head;
        while(p!=NULL){//按原结点改变的label编号和新结点在数组中的位置,给新结点的random赋值
           RandomListNode *tmp = p->random;
           if(tmp != NULL){
             r_tail->random = r_pointer[tmp->label];
           }
           p = p->next;
           r_tail = r_tail->next;
        }
    
        r_tail = r_head;
        p = head;
        while(p!= NULL)//将原结点的label变回原样
        {
          p->label = r_tail->label;
          p = p->next;
          r_tail = r_tail->next;
        }
        return r_head;
     }
  • 相关阅读:
    虚拟化VMware之虚拟机备份(1)
    虚拟化VMware之虚拟机备份(1)
    柯塔娜大合唱,互联网安全观
    柯塔娜大合唱,互联网安全观
    如何在虚拟机上Centos系统安装Nginx服务
    给已验证登录的用户添加访问限制
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    login_required装饰器(1)
    Oracle 18c 新特性:动态 Container Map 增强 Application Container 灵活性
    如果登录不成功,跳转到登录页面
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3848251.html
Copyright © 2011-2022 走看看