func copyRandomList(head *Node) *Node {
if head == nil {
return head
}
// 第一次遍历,先记录当前节点与新节点的映射关系
m := make(map[*Node]*Node)
for cur := head; cur != nil; cur = cur.Next {
m[cur] = &Node{Val: cur.Val}
}
// 第二次遍历,给新节点加上需要指向的rand节点,并且把新节点串联起来
for cur := head; cur != nil; cur = cur.Next {
m[cur].Next = m[cur.Next]
m[cur].Random = m[cur.Random]
}
return m[head]
}
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
//判断特殊情况
if(head == NULL) return NULL;
//根据next 指针复制节点
Node* cur = head;
while(cur)
{
Node* np = new Node(cur -> val);
Node* next = cur -> next;
cur -> next = np;
np -> next = next;
cur = next;
}
//完善节点的Random 指针
cur = head;
while(cur)
{
cur -> next -> random = cur -> random == NULL ? NULL : cur -> random -> next;
cur = cur -> next -> next;
}
//拆分链表 A->A1->B->B1->C->C1 为A->B->C 和A1->B1->C1
cur = head;
Node* headNew = head -> next;
Node* curNew = head -> next;
while(cur)
{
cur -> next = cur -> next -> next;
cur = cur -> next;
curNew -> next = cur == NULL ? NULL : cur -> next;
curNew = curNew -> next;
}
return headNew;
}
};
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
cur = head
# copy
while (cur):
nextcur = cur.next
cur.next = Node(cur.val)
cur.next.next = nextcur
cur = cur.next.next
cur = head
# copy random
while (cur):
if (cur.random):
cur.next.random = cur.random.next
else:
cur.next.random = None
cur = cur.next.next
cur = head
newhead = head.next
# delete
while (cur):
newcur = cur.next
cur.next = cur.next.next # already link A and B
if (newcur.next):
newcur.next = newcur.next.next
else:
newcur.next = None
cur = cur.next # not cur.next.next
return newhead
class Solution {
public:
Node* copyRandomList(Node* head) {
//边界条件:head判空
if(head nullptr) return nullptr;
Node* p = head;
unordered_map<Node*, Node*> map;
//copy each node, and build up hash-map
while(p != nullptr){
map[p] = new Node(p->val);//attention! this is an intact node
p = p->next;
}
//p return to head
p = head;
//build up new linklist's next and random
while(p != nullptr){
map[p] -> next = map[p -> next];
map[p] -> random = map[p -> random];
p = p->next;
}
return map[head];
}
var copyRandomList = function(head) {
// 边界判断
if(!head) return null
// 复制节点
let cur = head
while(cur) {
let next = cur.next
cur.next = new Node(cur.val)
cur.next.next = next
cur = next
}
// 复制随机节点
cur = head
while(cur) {
let curNew = cur.next
curNew.random = cur.random === null ? null : cur.random.next
cur = cur.next.next
}
// 拆分
let newHead = head.next
cur = head
curNew = head.next
while(cur) {
cur.next = cur.next.next
cur = cur.next
curNew.next = cur === null ? null : cur.next
curNew = curNew.next
}
return newHead
};
共以下 51 个回答
时间复杂度O(n)
空间复杂度O(1)
一种hashmap 一种聚合拆分,关键点找到新链表的random,只能通过旧链表来找。拆分时注意最后结点的拆分
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
}
*/
// class Solution {
// public Node copyRandomList(Node head) {
// if(headnull){
// return null;
// }
// Map<Node,Node> map=new HashMap();
// Node cur=head;
// while(cur!=null){
// Node temp=new Node(cur.val);
// map.put(cur,temp);
// cur=cur.next;
// }
// cur=head;
// while(cur!=null){
// map.get(cur).next=map.get(cur.next);
// map.get(cur).random=map.get(cur.random);
// cur=cur.next;
// }
// return map.get(head);
// }
// }
class Solution {
public Node copyRandomList(Node head) {
if(headnull){
return null;
}
Node cur=head;
while(cur!=null){
Node temp=new Node(cur.val);
temp.next=cur.next;
cur.next=temp;
cur=temp.next;
}
}
注意代码中指针所指节点为空的情况
迭代,先复制节点,再拆分
O(n), O(1)
// 时间复杂度on 空间复杂度on 构建 原链表节点 和 新链表对应节点 的键值对映射关系,再遍历构建新链表各节点的 next 和 random 引用指向
class Solution {
public Node copyRandomList(Node head) {
if(head null) return null;
Node cur = head;
Map<Node, Node> map = new HashMap<>();
}
一直没想明白原来要新建个链表😂
太难了 拆分-重组方法
时间复杂度O(n)空间复杂度O(n)思路:用map记录每个结点的下标,随机结点的下标位置和复制的链表相同
时间复杂度O(N),空间复杂度O(N)
空间复杂度还可以优化成O(1)
public Node copyRandomList(Node head) {
if(headnull)
{
return null;
}
//难点在复制的时候 romdom的指向 因为后面还没创建
HashMap<Node,Node> map=new HashMap<Node,Node>();
Node cur;
cur=head;
//遍历第一次 构造新节点
while(cur!=null)
{
map.put(cur,new Node(cur.val));
cur=cur.next;
}
cur=head;
//第二遍 填装新节点
while(cur!=null)
{
map.get(cur).next=map.get(cur.next);
map.get(cur).random=map.get(cur.random);
cur=cur.next;
}
return map.get(head);
哈希表
class Solution {
public:
Node* copyRandomList(Node* head) {
//边界条件:head判空
if(head nullptr) return nullptr;
Node* p = head;
unordered_map<Node*, Node*> map;
};
时间复杂度On
public Node copyRandomList(Node head) {
if (head null) {
return head;
}
//将拷贝节点放到原节点后面,例如1->2->3这样的链表就变成了这样1->1′->2->2′->3->3′
for (Node node = head, copy = null; node != null; node = node.next.next) {
copy = new Node(node.val);
copy.next = node.next;
node.next = copy;
}
//把拷贝节点的random指针安排上
for (Node node = head; node != null; node = node.next.next) {
if (node.random != null) {
node.next.random = node.random.next;
}
}
//分离拷贝节点和原节点,变成1->2->3和1′->2′->3’两个链表,后者就是答案
Node newHead = head.next;
for (Node node = head, temp = null; node != null && node.next != null;) {
temp = node.next;
node.next = temp.next;
node = temp;
}
时间复杂度空间复杂度都为O(n)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if (!head) {
return nullptr;
}
// 复制链表节点
Node* cur = head;
while (cur) {
Node* next = cur->next;
cur->next = new Node(cur->val);
cur->next->next = next;
cur = next;
}
};
//时间复杂度 O(n)
//空间复杂度O(1)
“`c++
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if(head= = NULL) return NULL;
Node *cur=head;
while(cur)
{
Node *next=cur->next;
cur->next=new Node(cur->val);
cur->next->next=next;
cur=next;
}
cur=head;
while(cur)
{
Node *New= cur ->next;
New ->random =cur->random = =NULL ? NULL: cur->random->next;
cur=cur->next->next;
}
Node *heNew=head->next;
Node *New=head->next;
cur=head;
while(cur)
{
cur->next = cur ->next ->next;
cur =cur->next;
New->next =cur= = NULL ? NULL : cur->next;
New = New->next;
}
return heNew;
}
};
代码
二
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
}
*/
class Solution {
public Node copyRandomList(Node head) {
if (head null) {
return null;
}
Node cur = head;
while (cur != null) {
Node next = cur.next;
cur.next = new Node(cur.val);
cur.next.next = next;
cur = next;
}
cur = head;
while (cur != null) {
Node curNew = cur.next;
curNew.random = cur.random null ? null : cur.random.next;
cur = cur.next.next;
}
Node headNew = head.next;
cur = head;
Node curNew = head.next;
while (cur != null) {
cur.next = cur.next.next;
cur = cur.next;
curNew.next = cur null ? null : cur.next;
curNew = curNew.next;
}
return headNew;
}
}
也就我用TS写了
T(n) = O(n) S(n)=O(n)
思路:
1. 使用哈希表建立旧节点与新节点的映射关系。
2. 遍历链表,将新节点进行连接。
时间复杂度 O(n) | 空间复杂度O(1)
复杂链表的复制。思路,遍历拷贝链表中每一个结点,拷贝插入到该节点之后。然后遍历一次复制出random指向的信息,遍历第二次复制出next指向的信息。 时间 O(n), 空间O(1)。
“`cpp
class Solution {
public:
Node* copyRandomList(Node* head) {
if (!head)return NULL;
};
“`有点模糊
c++ 代码 哈希
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head nullptr) return nullptr;
Node* cur = head;
unordered_map<Node*, Node> map;
// 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
while(cur != nullptr) {
map[cur] = new Node(cur->val);
cur = cur->next;
}
cur = head;
// 4. 构建新链表的 next 和 random 指向
while(cur != nullptr) {
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
// 5. 返回新链表的头节点
return map[head];
}
};
c++ 重组拆分代码
class Solution {
public:
Node copyRandomList(Node* head)
{
if(headNULL) return NULL;
Node* cur=head;
while(cur)//构建新的链表
{
Node* temp=new Node(cur->val);
temp->next=cur->next;
cur->next=temp;
cur=temp->next;
}
cur=head;
while(cur)//重新指定Random
{
if(cur->random!=NULL)
cur->next->random=cur->random->next;
cur=cur->next->next;
}
Node* pre=head;
Node *fol=head->next;
cur=head->next;
while(cur->next!=NULL)
{
pre->next=pre->next->next;
cur->next=cur->next->next;
pre=pre->next;
cur=cur->next;
}
pre->next=NULL;
return fol;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
时间复杂度O(n),O(n)
时间复杂度:O(n)
空间复杂度:O(n)
时间复杂度:O(n)
空间复杂度:O(n)
”’java
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> map = new HashMap<>();
for(Node cur = head;cur != null;cur = cur.next){
map.put(cur,new Node(cur.val));
}
for(Node cur = head;cur != null;cur = cur.next){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
}
return map.get(head);
}
}
”’
时间复杂度O(n)
空间复杂度O(N)
代码如下
边界判断、复制节点、复制随机节点、拆分
先拼接,再拆分
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head null) return null;
Node cur = head;
}
时间复杂度:O(N)
空间复杂度:O(N)
C++,使用map
class Solution {
public:
Node* copyRandomList(Node* head) {
Node* cur=head;
unordered_map<Node,Node> m;
while(cur!=NULL){
m[cur] = new Node(cur->val);
cur=cur->next;
}
cur=head;
while(cur!=NULL){
m[cur]->next=m[cur->next];
m[cur]->random=m[cur->random];
cur=cur->next;
}
return m[head];
}
};
时间复杂度:O(n);
空间复杂度:O(n);
时间复杂度:O(n)
空间复杂度:O(n)
2023.7.8
Day2:下面是代码
一般理解,之后还要再刷再理解。