剑指35 复杂链表的复制

Posted rookiez

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指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 };

 

以上是关于剑指35 复杂链表的复制的主要内容,如果未能解决你的问题,请参考以下文章

Java 剑指offer(35) 复杂链表的复制

剑指Offer35.复杂链表的复制

leetcode 剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制