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

    请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

    这题首先思路就比较复杂。

    如果直接复制好基础链表,再复制random指针,就需要O(n^2)的时间,比较慢。

    如果用哈希表记录下来每个节点的指针,可以化简到O(n),但是也需要O(n)的辅助空间。

    最优方法为先复制每个节点,并插入在原节点后面;然后为每个复制节点建立random指针,这样random的目标直接就是原节点random的下一个节点;最后把复制的节点拆出来即可。

    这里有两个点需要注意,一个是一定要留一个dummyhead指针指向链表头,否则会出现返回的是链表尾的情况;

    第二个是在复制或者建立random指针时,原指针和copy指针会同步往后移动,要注意先移动原指针,因为最多也是移动为nullptr,同时在移动copy指针前要判断原指针是否已经为null,否则会出现访问null的情况。

     1 /*
     2 // Definition for a Node.
     3 class Node {
     4 public:
     5     int val;
     6     Node* next;
     7     Node* random;
     8     
     9     Node(int _val) {
    10         val = _val;
    11         next = NULL;
    12         random = NULL;
    13     }
    14 };
    15 */
    16 class Solution {
    17 public:
    18     Node* copyRandomList(Node* head) {
    19         if(head==nullptr)
    20             return nullptr;
    21         return copyeach(head);
    22     }
    23 
    24     Node* copyeach(Node* head){
    25         Node* cur=head;
    26         while(cur!=nullptr){
    27             Node* copy=new Node(cur->val);
    28             copy->next=cur->next;
    29             cur->next=copy;
    30             cur=copy->next;
    31         }
    32         return establish_random(head);
    33     }
    34 
    35     Node* establish_random(Node* head){
    36         Node* origin=head,*copied=head->next;
    37         while(origin!=nullptr){
    38             if(origin->random!=nullptr){
    39                 copied->random=origin->random->next;
    40             }
    41             origin=copied->next;
    42             if(origin!=nullptr)
    43                 copied=origin->next;
    44         }
    45         /*
    46         Node* temp=head;
    47         while(temp!=nullptr){
    48             if(temp->random!=nullptr)
    49                 cout<<"val:"<<temp->val<<",random:"<<temp->random->val<<endl;
    50             else
    51                 cout<<"val:"<<temp->val<<",null"<<endl;
    52             temp=temp->next;
    53         }
    54         */
    55         return split(head);
    56     }
    57 
    58     Node* split(Node* head){
    59         Node* copied=head->next,*dummyhead=copied;
    60         while(head!=nullptr){
    61             head->next=copied->next;
    62             head=head->next;
    63             if(head==nullptr)
    64                 break;
    65             copied->next=head->next;
    66             copied=copied->next;
    67         }
    68         return dummyhead;
    69     }
    70 };
  • 相关阅读:
    Java修饰符/关键字
    深入理解Java面向对象三大特性 封装 继承 多态
    BUG为什么越改越多,越改越乱
    DDMS调试Virtual Box android虚拟机
    android开发之android虚拟机配置
    使用cordova 出现Error: The provided path is not Android project.
    Javascript与Flex AS3的交互
    [Ljava.lang.String; cannot be cast to java.lang.String错误
    使用Flex4的PopUpManager的addPopUp() 方法弹出 removeChild异常的解决办法
    Flex 4 不同主题下容器子元素的管理方法
  • 原文地址:https://www.cnblogs.com/rookiez/p/13235176.html
Copyright © 2011-2022 走看看