# Definition for a Node.
class Node:
def __init__(self, x, next=None, random=None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution(object):
def copyRandomList(self, head):
"""
:type head: Node
:rtype: Node
"""
if not head:
return None
# 复制链表节点
cur = head
while cur is not None:
next = cur.next
cur.next = Node(cur.val)
cur.next.next = next
cur = next
# 复制random指针
cur = head
while cur != None:
curNew = cur.next
curNew.random = cur.random.next if cur.random else None
cur = cur.next.next
# 拆分链表
cur = head
head_new = head.next
curNew = head.next
while cur:
cur.next = cur.next.next
cur = cur.next
curNew.next = cur.next if cur else None
curNew = curNew.next
return head_new
时间复杂度:o(n),空间复杂度o(n)
思路:使用一个哈希表来存储新的节点是否创建,未创建的换创建这个节点并存入哈希表中,一直递归知道head为nullptr
/*
// 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:
unordered_map<Node, Node*> Nodecache;
class Solution:
cache = dict()
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
if head not in self.cache:
self.cache[head] = Node(head.val)
self.cache[head].next = self.copyRandomList(head.next)
self.cache[head].random = self.copyRandomList(head.random)
return self.cache[head]
时间On 空间On
1.不管random复制整个链表,使用map存储原链表的每个node地址对应新链表的node地址;
2.遍历链表,依据map填充新链表的random
/*
// 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 nullptr) {
return nullptr;
}
map<Node*, Node*> m;
Node *tmp = new Node(head->val);
Node *p = head->next;
Node *q = tmp;
m[head] = q;
while (p != nullptr) {
q->next = new Node(p->val);
m[p] = q->next;
p = p->next;
q = q->next;
}
q = tmp;
p = head;
while (q != nullptr) {
q->random = m[p->random];
p = p->next;
q = q->next;
}
return tmp;
}
};
class Node:
def init(self, x: int, next: ‘Node’ = None, random: ‘Node’ = None):
self.val = int(x)
self.next = next
self.random = random
“””
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head: return
cur = head
#把原链表的每个节点在原链表中复制一份,复制的节点属于原节点的next
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = cur.next
#把复制的节点的random指向改变
cur = head
while cur:
if cur.random:
cur.next.random = cur.random
cur = cur.next
#把复制的链表拆出来
cur = res = head.next
pre = head
while cur.next:
pre.next = pre.next.next
cur.next = cur.next.next
pre = pre.next
cur = cur.next
pre.next = None
return res
共以下 35 个回答
使用hashmap打卡成功
时间n 空间n
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
}
*/
class Solution {
Map<Node,Node> cachedNode=new HashMap<Node,Node>();
public Node copyRandomList(Node head) {
}
时间复杂度:O(n)
空间复杂度:O(1)
“””
普通节点复制—->随机节点指向复制—->最后进行链表的拆分
“””
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head NULL) {
return NULL;
}
// 复制链表节点,如1->2>3为:1->1′->2->2′->3->3′
Node *cur = head;
while (cur != NULL) {
Node *newNode = new Node(cur->val);
newNode->next = cur->next;
cur->next = newNode;
cur = newNode->next;
}
// 复制random节点,同上,指向原random的next即可
cur = head;
while (cur != NULL && cur->next != NULL) {
Node *next = cur->next;
next->random = ((cur->random NULL) ? NULL : cur->random->next);
cur = next->next;
}
// 拆分节点,把两条链表分开
cur = head;
Node *head_new = head->next;
Node *cur_new = head->next;
while (cur != NULL && cur->next != NULL) {
cur->next = cur_new->next;
cur = cur_new->next;
if (cur_new->next != NULL) {
cur_new->next = (cur->next NULL ? NULL : cur->next);
cur_new = cur_new->next;
}
}
};
“””
//链表中有next指针和random指针要将两个指针复制到单个数字后面
//之后再进行分割
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 *cur = cur->next;
curNew->random= cur->random?cur->random ->next:NULL;
cur = cur->next->next;
}
//拆分
Node *headNew= head->next;
cur = head;
Node *curNew = head->next;
while(cur)
{
cur ->next = cur->next->next;
cur = cur ->next;
curNew->next – cur?cur->next:NULL;
curNew = curNew->next;
}
return headNew;
}
思路
解题方法
复杂度
时间复杂度:
空间复杂度:
Code
class Solution {
public:
Node* copyRandomList(Node* head) {
if(headnullptr) {
return nullptr;
}
for(Node* node =head; node !=nullptr; node=node->next->next){
Node* nodeNew = new Node(node->val);
nodeNew->next = node->next;
node->next = nodeNew;
}
for(Node* node = head; node!=nullptr; node=node->next->next){
Node* nodeNew = node->next;
nodeNew->random = (node->random!=nullptr)? node->random->next:nullptr;
}
Node* headnew = head->next;
for(Node* node =head; node!=nullptr;node=node->next){
Node* nodeNew=node->next;
node->next = node->next->next;
nodeNew->next=(nodeNew->next != nullptr)? nodeNew->next->next : nullptr;
}
return headnew;
}
};
时间复杂度: O(N)
空间复杂度:O(N)
哈希表+回溯(题解中的方法)
时间复杂度:o(n)
空间复杂度:o(n)
struct node * randomList(struct node * head)
{
//判断链表是否为空
if(head NULL)
{
return NULL;
}
}//时间复杂度为O(n),空间复杂度为O(1)
class Solution {//先用cur走一遍,链式存储一下,第二次map【random】就不会指向空值。
public:
Node* copyRandomList(Node* head) {
if(headnullptr)return nullptr;
};
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
/
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
// class Solution {
// public:
// Node copyRandomList(Node* head) {//遍历复制next random无法做到;
// Node* cur =head;
// Node* dum= new Node(0),pre =dum;
// while(cur!=nullptr){
// Node node=new Node(cur->val);
// pre->next=node;
// cur=cur->next;
// pre=node;
// }
// return dum->next;
// }
// };
//先复制节点,再将各个节点的random重新分配指向。
//时间复杂度为o(n)
//空间复杂度为o(1)
class Solution {
public:
Node* copyRandomList(Node* head) {
};
思路:使用复制 + 拆分:复制就是指原链表的每个节点的都构建出一个指相同的节点,新节点放在原节点的后面,然后遍历链表的原节点,使cur.next.random 指向 cur.random.next,拆分时记录当前节点的next节点,使当前节点的next指向当前的next的next,直到cur.next为空时停止
时间复杂度:O(n),空间复杂度:O(n)
class Solution {
public Node copyRandomList(Node head) {
if(head null) {
return head;
}
// 复制节点
Node cur = head;
while(cur != null) {
Node newNode = new Node(cur.val);
newNode.next = cur.next;
cur.next = newNode;
cur = cur.next.next;
}
// 遍历链表的原节点,使cur.next.random 指向 cur.random.next
cur = head;
while(cur != null) {
cur.next.random = cur.random null ? null : cur.random.next;
cur = cur.next.next;
}
// 拆分链表成两个链表
cur = head;
Node newHead = cur.next;
Node curNext = null;
while(cur.next != null) {
curNext = cur.next;
cur.next = cur.next.next;
cur = curNext;
}
return newHead;
}
}
复制链表,复制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;
}
}
/*
打卡
// 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;
}
}
打卡
先复制再拆分:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if(headNULL){
return NULL;
}
Node *cur=head;
while(cur!=NULL){
Node *copy=new Node(cur->val);
copy->next=cur->next;
cur->next=copy;
cur=cur->next->next;
}
cur=head;
while(cur!=NULL){
if(cur->random!=NULL)
cur->next->random=cur->random->next;
cur=cur->next->next;
}
cur=head;
Node *copyHead = head->next;
Node *curCopy = head->next;
while (cur != NULL) {
cur->next = cur->next->next;
cur = cur->next;
if (curCopy->next != NULL) {
curCopy->next = curCopy->next->next;
curCopy = curCopy->next;
}
}
return copyHead;
//return cur;
}
};
看完思路可以自己写出来
没理解:
curNew.random = cur.random null ? null : cur.random.next;
curNew.next = cur null ? null : cur.next;
为什么会有null
时间复杂度O(n)
空间复杂度O(n)
时间复杂度:o(n),空间复杂度o(n)
思路:使用一个哈希表来存储新的节点是否创建,未创建的换创建这个节点并存入哈希表中,一直递归知道head为nullptr
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
unordered_map<Node, Node*> Nodecache;
};
Node* copyRandomList(Node* head) {
if(headnullptr) return nullptr;
Node* dummy = new Node(0);
dummy->next = nullptr;
dummy->random = nullptr;
時間複雜度: O(n) 空間複雜度 O(n)
核心思路是遍歷兩次原始鏈表,第一次創建新節點並建立原始節點到新節點的映射(這邊使用哈希表來儲存),第二次處理 random 指針的關係並設置新節點的 random 指針。這樣可以在保持線性時間複雜度的同時完成複製。
时间复杂度:O(N), 空间复杂度:O(N)
复制链表需要创造新的空白链表
空间复杂度 O(N)
时间复杂度O(N2)
本题是主要是三个关键问题:
1.如何获得Random指针的元素地址
遇到类似问题可以先把这个代码写完
2、因为random是随机的,则需要遍历两遍链表,第一次只是复制全链表,不管random的值,第二次则是真复制random
3、第三个关键则为复制节点,由于复制节点,要考虑连接关系,所以我采用了虚拟头结点,来保持next的连接关系。否则的话则需要保持prev节点
1.不管random复制整个链表,使用map存储原链表的每个node地址对应新链表的node地址;
2.遍历链表,依据map填充新链表的random
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if (head nullptr) {
return nullptr;
}
map<Node*, Node*> m;
Node *tmp = new Node(head->val);
Node *p = head->next;
Node *q = tmp;
m[head] = q;
while (p != nullptr) {
q->next = new Node(p->val);
m[p] = q->next;
p = p->next;
q = q->next;
}
q = tmp;
p = head;
while (q != nullptr) {
q->random = m[p->random];
p = p->next;
q = q->next;
}
return tmp;
}
};
1、哈希表
这个题没做出来
“`python
本题的核心问题在于,复制。原始的单链表复制起来简单,本题的复制问题在于节点的random不好复制,因为random无法在遍历的时候按照某个规则确定指向。因此,我们遵循最原始的复制逻辑,复制结点之后,把这个复制的新节点的random改成和原节点一样的就可以了。
“””
Definition for a Node.
class Node:
def init(self, x: int, next: ‘Node’ = None, random: ‘Node’ = None):
self.val = int(x)
self.next = next
self.random = random
“””
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head: return
cur = head
#把原链表的每个节点在原链表中复制一份,复制的节点属于原节点的next
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = cur.next
时间O(n)空间O(1)
采用哈希表Map,将原节点和新节点放入Map中,第二次遍历原链表,根据原链表的节点访问到新链表节点,访问到Map中next节点及random节点连接起来。
暴力法
时间复杂度O(n2)空间复杂度O(1)