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

    题目地址:here

    题目大意:深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向字符串中的某个节点或者为空。

    节点定义为:

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

    假设原始链表如下,细线表示next指针,粗线表示random指针,没有画出的指针均指向NULL:

    算法1:我们在构建新链表的节点时,保存原始链表的next指针映射关系,并把指针做如下变化(蓝色为原始链表节点,紫红色为新链表节点):

    然后在上图的基础上进行如下两步

    1、构建新链表的random指针:比如new1->random = new1->random->random->next, new2->random = NULL, new3-random = NULL, new4->random = new4->random->random->next

    2、恢复原始链表:根据最开始保存的原始链表next指针映射关系恢复原始链表

    该算法时间空间复杂度均为O(N)


    算法2:该算法更为巧妙,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:

    同理分两步

    1、构建新节点random指针:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next

    2、恢复原始链表以及构建新链表:例如old1->next = old1->next->next,  new1->next = new1->next->next

    该算法时间复杂度O(N),空间复杂度O(1)


    下面分别为算法1和算法2代码:

     1 class Solution {
     2 public:
     3     RandomListNode *copyRandomList(RandomListNode *head)
     4      {
     5         // Note: The Solution object is instantiated only once and is reused by each test case.
     6         if(head == NULL)return NULL;
     7         std::map<RandomListNode *,RandomListNode *> oldlistMap;
     8         RandomListNode *result = new RandomListNode(head->label) ;
     9         RandomListNode *pold = head, *pnew = result;
    10         pnew->random = pold;
    11         //pold->next = pnew;
    12         RandomListNode* poldPre = pold, *pnewPre = pnew;
    13         while(pold->next != NULL)
    14         {
    15             //保存old list的next指针
    16             oldlistMap.insert(std::map<RandomListNode*,
    17                               RandomListNode*>::value_type(pold, pold->next));
    18             pold = pold->next;
    19             poldPre->next = pnew;
    20             pnew = new RandomListNode(pold->label);
    21             pnewPre->next = pnew;
    22             pnew->random = pold;
    23 
    24             poldPre = pold;
    25             pnewPre = pnew;
    26         }
    27         pold->next = pnew;//设置old list最后一个节点
    28 
    29         //设置new list的random指针
    30         pnew = result;
    31         while(pnew != NULL)
    32         {
    33             if(pnew->random->random)
    34                 pnew->random = pnew->random->random->next;
    35             else pnew->random = NULL;
    36             pnew = pnew->next;
    37         }
    38         //恢复old list的next指针
    39         pold = head;
    40         for(int i = 1; i <= oldlistMap.size(); i++)
    41         {
    42             pold->next = oldlistMap[pold];
    43             pold = pold->next;
    44         }
    45         pold->next = NULL;//old list 最后一个节点
    46 
    47         return result;
    48     }
    49 };
     1 class Solution {
     2 public:
     3     RandomListNode *copyRandomList(RandomListNode *head)
     4      {
     5         // Note: The Solution object is instantiated only once and is reused by each test case.
     6         if(head == NULL)return NULL;
     7         RandomListNode *result = NULL;
     8         RandomListNode *pold = head, *pnew = result, *poldNext = NULL;
     9         do
    10         {
    11             poldNext = pold->next;
    12             pnew = new RandomListNode(pold->label);
    13             pold->next = pnew;
    14             pnew->next = poldNext;
    15 
    16             if(result == NULL)
    17                 result = pnew;
    18             pold = poldNext;
    19         }while(pold);
    20         //设置new list的random指针
    21         pold = head;
    22         while(pold)
    23         {
    24             if(pold->random)
    25                 pold->next->random = pold->random->next;
    26             pold = pold->next->next;
    27         }
    28         //恢复old list 和new list
    29         pold = head;
    30         pnew = result;
    31         while(pnew->next)
    32         {
    33             pold->next = pnew->next;
    34             pold = pold->next;
    35             pnew->next = pold->next;
    36             pnew = pnew->next;
    37         }
    38         pold->next = NULL;
    39         pnew->next = NULL;
    40         return result;
    41     }
    42 };

     【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3387000.html

  • 相关阅读:
    线程的中断.interrupt
    线程的加入.join()
    Runnable接口
    线程Thread类
    求和、均值
    最值、对应索引位置
    数组、冒泡排序
    获取Methods成员方法类
    获取Field成员变量类
    基于WinDbg的内存泄漏分析
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3387000.html
Copyright © 2011-2022 走看看