-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCopyRandomList.cpp
More file actions
168 lines (113 loc) · 3.17 KB
/
CopyRandomList.cpp
File metadata and controls
168 lines (113 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//
// Created by Wanhui on 2/25/20.
//
#include <map>
#include "CopyRandomList.h"
Node *Solution35::copyRandomList(Node *head) {
if (head == nullptr) {
return head;
}
copyNodes(head);
connectRandomNode(head);
return splitCopyNodeList(head);
}
void Solution35::copyNodes(Node *head) {
Node *node = head;
while (node != nullptr) {
Node *copyNode = new Node(0);
// 复制节点
copyNode->val = node->val;
copyNode->next = node->next;
copyNode->random = nullptr;
// 将复制节点挂在原节点后
node->next = copyNode;
node = copyNode->next;
}
}
void Solution35::connectRandomNode(Node *head) {
Node *node = head;
while (node != nullptr) {
Node *copyNode = node->next;
// 复制random指针
if (node->random != nullptr) {
copyNode->random = node->random->next;
}
node = copyNode->next;
}
}
Node *Solution35::splitCopyNodeList(Node *head) {
Node *node = head;
Node *copyHead = nullptr;
Node *copyNode = nullptr;
// 因为是返回拆分后的链表
// 所以先要将原链表第一个节点拆除
if (node != nullptr) {
copyHead = node->next;
copyNode = copyHead;
node->next = copyNode->next;
node = node->next;
}
// 拆出复制的链表
while (node != nullptr) {
copyNode->next = node->next;
copyNode = copyNode->next;
node->next = copyNode->next;
node = node->next;
}
return copyHead;
}
Node *Solution35::copyRandomList2(Node *head) {
if (head == nullptr) {
return head;
}
std::map<Node *, Node *> visited;
visited[nullptr] = nullptr;
Node *prev = nullptr;
Node *node = head;
// 建立原链表的哈希表,
// 使用map存储原节点与复制节点的对应关系
while (node != nullptr) {
Node *newNode = new Node(head->val);
visited[node] = newNode;
node = node->next;
}
// 重置node节点
node = head;
// 复制链表的每个节点
while (node != nullptr) {
// 从复制链表的第一个节点开始
// newNode作为临时节点
Node *newNode = visited[node];
// 复制节点的value和random指针
newNode->val = node->val;
newNode->random = visited[node->random];
newNode->next = nullptr;
// 连接复制链表的每个节点
// 复制next指针
if (prev != nullptr) {
visited[prev]->next = newNode;
}
prev = node;
node = node->next;
}
return visited[head];
}
Node *Solution35::copyRandomList3(Node *head) {
std::map<Node *, Node *> visited;
if (head == nullptr) {
return head;
}
// 回溯结束条件
if (visited.count(head)) {
return visited[head];
}
// 复制节点且复制值
Node *node = new Node(head->val);
// 做选择
visited[head] = node;
// 进入下一层决策
// 复制next和random指针
node->next = copyRandomList3(head->next);
node->random = copyRandomList3(head->random);
return node;
}