python”’
def copyRandomList(self, head):
“””
:type head: Node
:rtype: Node
“””
# 返回 RandomListNode
if head is None:
return None
# 复制
temp = head
while temp:
node = Node(temp.val)
node.next = temp.next
temp.next = node
temp = node.next
# 实现新建node的random指向
temp = head
while temp:
if temp.random:
temp.next.random = temp.random.next
temp = temp.next.next
# 拆分成两个链表
Nhead = head
res = head.next
while head.next:
tmp = head.next
head.next = tmp.next
head = tmp
return res
”’python
思路:先复制链表,再将链表进行拆分
class Solution(object):
def copyRandomList(self, head):
“””
:type head: Node
:rtype: Node
“””
if not head:
return None
# 复制链表节点
cur = head
while cur:
next = cur.next
cur.next = Node(cur.val)
cur.next.next = next
cur = next
# 复制随机节点
cur = head
while cur:
curNew = cur.next
curNew.random = cur.random.next if cur.random else None
cur = cur.next.next
# 拆分,比如把 A->A1->B->B1->C->C1拆分成 A->B->C和A1->B1->C1
headNew = head.next
cur = head
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 headNew
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head:
return
hamp = {}
cur = head
while cur:
hamp[cur] = Node(cur.val)
cur = cur.next
cur = head
while cur:
hamp[cur].next = hamp.get(cur.next)
hamp[cur].random = hamp.get(cur.random)
cur = cur.next
return hamp[head]
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head: return
cur = head
# 1. 复制各节点,并构建拼接链表
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
# 2. 构建各新节点的 random 指向
cur = head
while cur:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
# 3. 拆分两链表
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 # 返回新链表头节点
看得题解 面试遇到我应该直接说不会
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head:
return None
# 使用哈希表存储每个节点对应的新节点
dic = {}; cur = head
# 添加映射对
while cur:
dic[cur] = Node(cur.val)
cur = cur.next
# 添加 next 和 random 关系
cur = head
newHead = dic[cur]
while cur:
newHead.next = dic.get(cur.next) #两种获取字典value的方法,get的这种可以容许None
newHead.random = dic[cur.random] if cur.random else None
cur = cur.next
newHead = newHead.next
return dic[head]
拼接
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
# 直接构建成 节点1->新节点1->节点2->新节点2 …
# 这样,每个新节点都可以通过旧节点的next访问到了
if not head:
return None
cur = head
while cur:
temp = cur.next
cur.next = Node(cur.val)
cur.next.next = temp
cur = temp
cur = head
while cur:
newCur = cur.next
temp = newCur.next
newCur.next = temp.next if temp else None
newCur.random = cur.random.next if cur.random else None
cur = temp
return head.next
var copyRandomList = function (head) {
if (head <span class="text-highlighted-inline" style="background-color: #fffd38;"> null) return null
let map = new Map()</span>
let cur = head
while (cur) {
map.set(cur, new Node(cur.val))
cur = cur.next
}
cur = head
while (cur) {
map.get(cur).next = map.get(cur.next) <span class="text-highlighted-inline" style="background-color: #fffd38;">= undefined ? null : map.get(cur.next);
map.get(cur).random = map.get(cur.random)
cur = cur.next
}</span>
return map.get(head)
};
共以下 48 个回答
python”’
def copyRandomList(self, head):
“””
:type head: Node
:rtype: Node
“””
# 返回 RandomListNode
if head is None:
return None
# 复制
temp = head
while temp:
node = Node(temp.val)
node.next = temp.next
temp.next = node
temp = node.next
复制和拆分的思路,建立兄弟链接为temp.next.random=temp.random.next
时间复杂度为O(n),空间复杂度为O(n)
”’python
思路:先复制链表,再将链表进行拆分
class Solution(object):
def copyRandomList(self, head):
“””
:type head: Node
:rtype: Node
“””
if not head:
return None
# 复制链表节点
cur = head
while cur:
next = cur.next
cur.next = Node(cur.val)
cur.next.next = next
cur = next
class Solution {
public Node copyRandomList(Node head) {
HashMap<Node,Node> hashmap=new HashMap<>();
Node virhead=new Node(-1);
Node temp_new=virhead;
Node temp=head;
while(temp!=null)
{
temp_new.next=new Node(temp.val);
hashmap.put(temp,temp_new.next);
temp=temp.next;
temp_new=temp_new.next;
}
temp_new=virhead;
temp=head;
while(temp!=null)
{
temp_new.next.random=hashmap.get(temp.random);
temp=temp.next;
temp_new=temp_new.next;
}
return virhead.next;
}
}
通过哈希表,记录之前链表和新链表节点之间的映射关系,从而完成新链表random指针的赋值
时间复杂度:O(n)
空间复杂度:O(1)
“c++
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head nullptr){
return nullptr;
}
Node* tmp = head;
while(tmp){
Node* new_h = new Node(tmp->val);
new_h->next = tmp->next;
tmp->next = new_h;
tmp = tmp->next->next;
}
tmp = head;
while(tmp){
if(tmp->random nullptr){
tmp->next->random = nullptr;
}else{
tmp->next->random = tmp->random->next;
}
tmp = tmp->next->next;
}
tmp = head;
Node* newhead = new Node(0);
Node* cur = newhead;
while(tmp){
cur->next = tmp->next;
cur = cur->next;
tmp->next = tmp->next->next;
tmp = tmp->next;
}
return newhead->next;
}
};
时间空间都为O(n)
思路:第一次很难想到先复制再拆分的想法
“`c++
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if(!head){
return NULL;
}
};
“`
犯错:思路混乱,且没有考虑到cur->random为空的情况
时间复杂度O(N)
空间复杂度O(N)
时间:O(n)
空间:O(n)
哈希,时间复杂度O(n),空间复杂度O(n)
class Solution {
public Node copyRandomList(Node head) {
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) {
Node temp = map.get(cur);
temp.next = map.get(cur.next);
temp.random = map.get(cur.random);
cur = cur.next;
}
return map.get(head);
}
}
时间复杂度O(n)
空间复杂度O(1)
这里复制指深拷贝,第一次看到这道题给搞晕了
时间复杂度o(n),空间复制度o(1)
分为复制节点、复制random指针、拆分节点三部分
一定要注意指针的变化情况
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
};
/
class Solution {
public:
Node copyRandomList(Node* head) {
if(headnullptr)
{
return nullptr;
}
//复制各节点
Node *cur = head;
Node *temp = head->next;
while(cur!=nullptr)
{
cur->next = new Node(cur->val);
cur->next->next = temp;
cur = temp;
temp = curnullptr?nullptr:cur->next;
}
//复制random节点
cur = head;
Node *randomptr = head->next;
while(cur!=nullptr)
{
randomptr->random = cur->randomnullptr?nullptr:cur->random->next;
cur = cur->next->next;
randomptr = randomptr->nextnullptr?nullptr:randomptr->next->next;
}
//拆分链表
cur = head;
Node *result = head->next;
Node *p1 = result;
while(cur!=nullptr)
{
cur->next = cur->next->next;
p1->next = p1->nextnullptr?nullptr:p1->next->next;
cur = cur->next;
p1 = p1->next;
}
return result;
}
};
public Node copyRandomList(Node head) {
if(head null) return null;
Node cur = head;
Map<Node, Node> map = new HashMap<>();
// 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
while(cur != null) {
map.put(cur, new Node(cur.val));
cur = cur.next;
}
cur = head;
// 4. 构建新链表的 next 和 random 指向
while(cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
// 5. 返回新链表的头节点
return map.get(head);
}
k神的题解 还要再想一下
时间复杂度:O(n)
空间复杂度:O(1)
哈希表解法,设置每个节点都是一项值,key值为当前节点对象,val值为节点的数值
遍布链表,设置每个节点的next节点为哈希表中获取其对象;
/*
// 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* tmp = head;
while(tmp){
Node* ntmp = new Node(tmp->val);
ntmp->next = tmp->next;
tmp->next = ntmp;
tmp = ntmp->next;
}
//random更新
tmp = head;
while(tmp){
if(tmp->random != nullptr)
tmp->next->random = tmp->random->next;
tmp = tmp->next->next;
}
//拆分
Node* cur = head->next;
Node* pre = head, *res = head->next;
while(cur->next){
pre->next=pre->next->next;
cur->next=cur->next->next;
pre = pre->next;
cur = cur->next;
}
pre->next = nullptr;
return res;
}
};
思路:Map存储新旧列表的节点,复杂度:O(n)
代码:
“`java map = new HashMap<>();
public Node copyRandomList(Node head) {
if (null == head) {
return null;
}
Node node = head;
Map
while(null != node) {
map.put(node, new Node(node.val));
node = node.next;
}
node = head;
while(null != node) {
map.get(node).next = map.get(node.next);
map.get(node).random = map.get(node.random);
node = node.next;
}
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head:
return
hamp = {}
时间复杂度:o(n)
空间复杂度:o(n)
/*
// 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;
Node cur = head;
unordered_map<Node, Node*> map;
while(cur)
{
map[cur] = new Node(cur->val);
cur = cur->next;
}
cur = head;
while(cur)
{
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
return map[head];
}
};
思路:使用map存下原本的节点和复制节点; 从map中取出直接节点赋值next和random指针;
时间复杂度: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;
Node next = null;
// copy node and link to every node
while (cur != null) {
next = cur.next;
cur.next = new Node(cur.val);
cur.next.next = next;
cur = next;
}
cur = head;
Node curCopy = null;
// set copy node random
while (cur != null) {
next = cur.next.next;
curCopy = cur.next;
curCopy.random = cur.random != null ? cur.random.next : null;
cur = next;
}
Node res = head.next;
cur = head;
// split
while (cur != null) {
next = cur.next.next;
curCopy = cur.next;
cur.next = next;
curCopy.next = next != null ? next.next : null;
cur = next;
}
return res;
}
}
时间复杂度为 O(n)
空间复杂度为 O(1)
时空复杂度O(N)
时间复杂度o(n) 空间复杂度o(n)
复制复杂链表
https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/solutions/2665412/fu-zhi-fu-za-lian-biao-by-yukislab-lyrg
哈希表方法:
class Solution {
public Node copyRandomList(Node head) {
if(head null)return null;
Node cur = head;
Map<Node, Node> map = new HashMap<>();
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) {
if(head null)return null;
Node cur = head;
while(cur != null){
Node tmp = new Node(cur.val);
tmp.next = cur.next;
cur.next = tmp;
cur = tmp.next;
}
cur = head;
while(cur != null){
if(cur.random != null){
cur.next.random = cur.random.next;
}
cur = cur.next.next;
}
cur = head.next;
Node pre = head;
Node res = 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 res;
}
使用哈希表存放节点对
时间复杂度为O(N),空间复杂度为O(N),
使用HashMap作为前后两个链表的关联结构,时间复杂度$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;
while(cur!=null){
Node next = cur.next;
cur.next = new Node(cur.val);
cur.next.next = next;
cur = next;
}
使用HashMap映射的方式实现复杂链表复制
根据题解
存在的问题:
使用HashMap解决
通过新Node节点和旧Node节点的绑定,依据旧节点next指针和random指针的对应关系,根据HashMap指针O(1)的搜索方式快速的形成对新节点的匹配!
思路:先复制链表节点,在复制随机节点,最后对复制的链表进行拆分。图解:https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/solutions/476617/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
时间复杂度 O(N)O(N)O(N) : 三轮遍历链表,使用 O(N)O(N)O(N) 时间。
空间复杂度 O(1)O(1)O(1) : 节点引用变量使用常数大小的额外空间。
/*
// 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;
Map<Node,Node> map = new HashMap<>();
while(head != null){
map.put(cur,new Node(cur.val));
cur = cur.next;
}
通过哈希表,来复制。思路容易理解,但代码实现很不熟练
时间复杂度O(n)
空间复杂度O(n)
class Solution {
public Node copyRandomList(Node head) {
HashMap<Node,Node> map = new HashMap();
Node ptr = head;
Node copyHead = new Node(0);
Node copyPtr = copyHead;
while(ptr != null){
copyPtr.next = new Node(ptr.val);
map.put(ptr,copyPtr.next);
copyPtr = copyPtr.next;
ptr = ptr.next;
}
ptr = head;
copyPtr = copyHead.next;
while(ptr != null){
copyPtr.random = map.get(ptr.random);
ptr = ptr.next;
copyPtr = copyPtr.next;
}
}
两次遍历链表。第一次完成next复制并通过hashmap记录对应关系,第二次完成random赋值
时间复杂度On 空间复杂度On
class Solution {
public Node copyRandomList(Node head) {
if (head null) return null;
HashMap<Node, Node> hashmap = new HashMap<>();
Node tmp = head;
while (tmp != null) {
hashmap.put(tmp, new Node(tmp.val));
tmp = tmp.next;
}
tmp = head;
while (tmp != null) {
hashmap.get(tmp).next = hashmap.get(tmp.next);
hashmap.get(tmp).random = hashmap.get(tmp.random);
tmp = tmp.next;
}
return hashmap.get(head);
}
}
使用哈希表
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head: return
cur = head
# 1. 复制各节点,并构建拼接链表
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
# 2. 构建各新节点的 random 指向
cur = head
while cur:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
# 3. 拆分两链表
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 # 返回新链表头节点
看得题解 面试遇到我应该直接说不会
看了题解才做出来
时间复杂度o(2n)
空间复杂度o(n)
##CPP
哈希表
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
if not head:
return None
# 使用哈希表存储每个节点对应的新节点
dic = {}; cur = head
# 添加映射对
while cur:
dic[cur] = Node(cur.val)
cur = cur.next
# 添加 next 和 random 关系
cur = head
newHead = dic[cur]
while cur:
newHead.next = dic.get(cur.next) #两种获取字典value的方法,get的这种可以容许None
newHead.random = dic[cur.random] if cur.random else None
cur = cur.next
newHead = newHead.next
return dic[head]
拼接
class Solution:
def copyRandomList(self, head: ‘Node’) -> ‘Node’:
# 直接构建成 节点1->新节点1->节点2->新节点2 …
# 这样,每个新节点都可以通过旧节点的next访问到了
if not head:
return None
cur = head
while cur:
temp = cur.next
cur.next = Node(cur.val)
cur.next.next = temp
cur = temp
cur = head
while cur:
newCur = cur.next
temp = newCur.next
newCur.next = temp.next if temp else None
newCur.random = cur.random.next if cur.random else None
cur = temp
return head.next
class Solution {
public Node copyRandomList(Node head) {
// 如果原链表为空,则直接返回空
if(head null) return null;
Node cur = head;
// 1. 复制各节点,并构建拼接链表
// 遍历原链表,对于每一个节点,创建一个新的节点,其值为原节点的值,然后将新节点插入到原节点和原节点的下一个节点之间
// 即形成一个新的交替排列的链表,原节点的 next 指向新节点,新节点的 next 指向原节点的下一个节点
while(cur != null) {
Node tmp = new Node(cur.val);
tmp.next = cur.next;
cur.next = tmp;
cur = tmp.next;
}
}
day2第三题
该题没有思路,直接看的讲解
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public:
Node* copyRandomList(Node* head) {
unordered_map<Node*, Node> map;
Node cur = head;
while (cur != nullptr){
map[cur] = new Node(cur->val);
cur = cur->next;
}
cur = head;
while (cur != nullptr){
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
return map[head];
}
};开始完全没思路,甚至都看不懂题。后面看了解析,一知半解,理解了用map来做。时空复杂度都是O(N)
···java
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> hashMap = new HashMap<>();
Node cur = head;
Node cur2 = head;
while(cur!=null){
hashMap.put(cur,new Node(cur.val,null,null));
cur = cur.next;
}
while(cur2!=null){
Node temp = hashMap.get(cur2);
temp.next = hashMap.get(cur2.next);
temp.random = hashMap.get(cur2.random);
cur2 = cur2.next;
}
return hashMap.get(head);
}
}
思路:建立链表中原来的节点与后面重新创建的节点之间的映射,然后通过映射来为新节点设置next和random
“`java map = new HashMap<>();
class Solution {
public Node copyRandomList(Node head) {
Node result = new Node(0);
Node tail = result;
Node cur = head;
Map
while(cur != null){
Node node = new Node(cur.val);
tail.next = node;
tail = node;
Node node2 = new Node(cur.val);
node2 = cur;
map.put(node2, node);
cur = cur.next;
}
cur = head;
tail = result.next;
while(cur != null){
Node random = map.get(cur.random);
tail.random = random;
cur = cur.next;
tail = tail.next;
}
return result.next;
}
}
“` 通过map存储新旧节点的对应关系,从而更新random指针
emm参考了别人的思路,初看时没有实现,后续将进一步看一下其他思路,整体理解一下。
时间复杂度: O(n)
空间复杂度:O(n)
“`c++ map;
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head == nullptr) return nullptr;
Node* cur = head;
unordered_map
while(cur != nullptr) {
map[cur] = new Node(cur->val);
cur = cur->next;
}
cur = head;
while(cur != nullptr) {
map[cur]->next = map[cur->next];
map[cur]->random = map[cur->random];
cur = cur->next;
}
return map[head];
}
};
“`