题目描述
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。 random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]] 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]] 示例 2:
输入:head = [[1,1],[2,1]] 输出:[[1,1],[2,1]] 示例 3:
输入:head = [[3,null],[3,0],[3,null]] 输出:[[3,null],[3,0],[3,null]] 示例 4:
输入:head = [] 输出:[] 解释:给定的链表为空(空指针),因此返回 null。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
js
/**
* // Definition for a Node.
* function Node(val, next, random) {
* this.val = val;
* this.next = next;
* this.random = random;
* };
*/
function Node(val, next, random) {
this.val = val;
this.next = next;
this.random = random;
}
//生成head
let listA = new Node(7,null,null);
(function(){
let la = listA,i=0, obj={};
obj[i++] = la;
la.next = new Node(13,null,null);
la = la.next;
obj[i++] = la;
la.next = new Node(11,null,null);
la = la.next;
obj[i++] = la;
la.next = new Node(10,null,null);
la = la.next;
obj[i++] = la;
la.next = new Node(1,null,null);
la = la.next;
obj[i++] = la;
obj[1].random = obj[0];
obj[2].random = obj[4];
obj[3].random = obj[2];
obj[4].random = obj[0];
})();
//copyRandomList(listA)
/**
* @param {Node} head
* @return {Node}
*/
var copyRandomList0 = function (head) {
let newHead = new Node(-1),
na = newHead,
la = head,
index = 0,
obj = {};
while (la) {
obj[index++] = {
map: la,
random: null
};
la = la.next;
}
la = head;
for (let key in obj) {
for (let k in obj) {
if (obj[key].map.random === obj[k].map) {
obj[key].random = k;
break;
}
}
}
la = head,
index = 0;
while (la) {
na.next = new Node(la.val, null, obj[index].random || null);
na = na.next;
obj[index++].map = na;
la = la.next;
}
na = newHead.next;
while (na) {
if (na.random) {
na.random = obj[na.random].map;
}
na = na.next;
}
// console.log(na)
return newHead.next;
};
var copyRandomList1 = function (head) {
let newHead = new Node(-1),
na = newHead,
la = head,
index = 0,
obj = {};
//这里就是做了个映射
//通过对比得到random是第几个节点
//obj map存储复制后的节点
while (la) {
let random = null;
if (la.random) {
let k = head,
i = 0;
while (k) {
if (la.random === k) {
random = i;
break;
}
k = k.next;
i++;
}
}
na.next = new Node(la.val, null, random);
na = na.next;
obj[index++] = na;
la = la.next;
}
//根据映射来赋值random
na = newHead.next;
while (na) {
if (na.random !== null) {
na.random = obj[na.random];
}
na = na.next;
}
return newHead.next;
};
//精髓就是 把当前节点作为key 深复制的新节点作为值
//然后 节点的random不为空时 去map里取对应 深复制的节点作为新链表节点的random
var copyRandomList2 = function (head) {
let newHead = new Node(-1),
na = newHead,
la = head,
map = new Map();
while (la){
na.next = new Node(la.val,null,null);
na = na.next;
map.set(la,na);
la = la.next;
}
la = head,
na = newHead.next;
while (la){
la.random && (na.random = map.get(la.random));
la = la.next;
na = na.next;
}
return newHead.next;
};
//原理就是复制当前节点并成为当前节点的next节点
//就形成了 A-A-B-B-C-C-null,前是原节点 后是复制的节点
//仔细观察 可以看出 原节点A的random 指向的节点的next 是复制后的节点
//所以当前节点存在random时 那么当前节点的next节点的random 就等于 当前节点的random节点的next
//最后再取出复制的节点并在原链表里删除
var copyRandomList = function (head) {
let lista = head,node=null,newHead = new Node(-1,null,null);
while (lista){
let tem = lista.next;
node = new Node(lista.val,null,null);
lista.next = node;
node.next = tem;
lista = tem;
}
lista = head;
while (lista){
if (lista.random){
lista.next.random = lista.random.next;
}
lista = lista.next.next;
}
node = newHead;
lista = head;
while (lista){
node.next = lista.next;
node = node.next;
lista.next = node.next;
lista = lista.next;
}
return newHead;
};
python
"""
# 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':
lista,newHead = head,Node(-1)
while lista:
tem = lista.next
node = Node(lista.val)
node.next = lista.next
lista.next = node
lista = tem
lista = head
while lista:
if lista.random:
lista.next.random = lista.random.next
lista = lista.next.next
lista = head
node = newHead
while lista:
node.next = lista.next
node = node.next
lista.next = node.next
lista = lista.next
return newHead.next
def copyRandomList1(self, head: 'Node') -> 'Node':
lista,newHead,index,obj = head,Node(-1),0,{}
nlist = newHead
while lista:
random = None
if lista.random:
k,i = head,0
while k:
if lista.random == k:
random = i
break
k = k.next
i+=1
nlist.next = Node(lista.val,None,random)
nlist = nlist.next
obj[index] = nlist
index+=1
lista = lista.next
nlist = newHead.next
while nlist:
if nlist.random != None:
nlist.random = obj[nlist.random]
nlist = nlist.next
return newHead.next
#生成题的链表
listA = Node(7)
la = listA
i=0
obj={}
obj[i] = la
i+=1
la.next = Node(13)
la = la.next
obj[i] = la
i+=1
la.next = Node(11)
la = la.next
obj[i] = la
i+=1
la.next = Node(10)
la = la.next
obj[i] = la
i+=1
la.next = Node(1)
la = la.next
obj[i] = la
i+=1
obj[1].random = obj[0]
obj[2].random = obj[4]
obj[3].random = obj[2]
obj[4].random = obj[0]
print(listA == Solution().copyRandomList(listA))
目的只是为了记录一下
python版本基本就是复刻的js。主要是为了熟悉一下python