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.

    最开始的想法就是暴力复制,时间复杂度为O(n^2),写的时候就感觉要出现事,果不其然,超时了,后来网上看到一个O(n)的算法,非常巧妙的利用了原来链表的信息:

    该算法更为巧妙,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:
     
     
    同理分两步
     
    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  * Definition for singly-linked list with a random pointer.
     3  * struct RandomListNode {
     4  *     int label;
     5  *     RandomListNode *next, *random;
     6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     RandomListNode *copyRandomList(RandomListNode *head) {
    12         if (head == NULL) return NULL;
    13         RandomListNode *pos1 = head, *pos2 = head->next;
    14         while (pos1 != NULL) {
    15             pos1->next = new RandomListNode(pos1->label);
    16             pos1->next->next = pos2;
    17             pos1 = pos2;
    18             if (pos2 != NULL)
    19                 pos2 = pos2->next;
    20         }
    21         pos1 = head;  pos2 = head->next;
    22         while (pos1 != NULL) {
    23             if (pos1->random == NULL) {
    24                 pos2->random = NULL;
    25             } else {
    26                 pos2->random = pos1->random->next;
    27             }
    28             pos1 = pos1->next->next;
    29             if (pos2->next != NULL)
    30                 pos2 = pos2->next->next;
    31         }
    32         RandomListNode *res = head->next;
    33         pos1 = head; pos2 = head->next;
    34         while(pos2->next != NULL) {
    35             pos1->next = pos2->next;
    36             pos1 = pos2;
    37             if (pos2->next != NULL)
    38                 pos2 = pos2->next;
    39         }
    40         pos1->next = NULL;
    41         pos2->next = NULL;
    42         return res;
    43     }
    44 };

    下面是最开始的超时的暴力复制代码:

     1 /**
     2  * Definition for singly-linked list with a random pointer.
     3  * struct RandomListNode {
     4  *     int label;
     5  *     RandomListNode *next, *random;
     6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     RandomListNode *copyRandomList(RandomListNode *head) {
    12         if (head == NULL) return NULL;
    13         RandomListNode *res = new RandomListNode(head->label);
    14         RandomListNode *pos1 = head->next, *pos2 = res;
    15         while (pos1 != NULL) {
    16             pos2->next = new RandomListNode(pos1->label);
    17             pos1 = pos1->next;
    18             pos2 = pos2->next;
    19         }
    20         pos1 = head;  pos2 = res;
    21         RandomListNode *idx1 = head, *idx2 = res;
    22         while (pos1 != NULL) {
    23             if (pos1->random == NULL) {
    24                 pos2->random = NULL;
    25             } else {
    26                 idx1 = head; idx2 = res;
    27                 while (pos1->random != idx1) {
    28                     idx1 = idx1->next;
    29                     idx2 = idx2->next;
    30                 }
    31                 pos2->random = idx2;
    32             }
    33             pos1 = pos1->next;
    34             pos2 = pos2->next;
    35         }
    36         return res;
    37     }
    38 };
  • 相关阅读:
    Linux nfs服务讲解
    Linux nfs服务介绍
    牛客网题目-数组中只出现1次的数字
    牛客网中矩阵中的路径
    求链表的第一个公共节点
    C++中STL中简单的Vector的实现
    牛客网栈的压入,和弹出序列
    C++智能指针
    CI Weekly #22 | flow.ci 新版 iOS 构建流程的 4 大变化
    CI Weekly #21 | iOS 持续集成快速入门指南
  • 原文地址:https://www.cnblogs.com/easonliu/p/3647160.html
Copyright © 2011-2022 走看看