「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
哈希表
借用哈希表存储新数据
假设现在有一个链表如下图所示
1、根据原链表创建新链表节点;7、13、11、10、1;这一步没问题吧?
2、暂时不需要知道新链表节点的关系,只需要将新建节点放在Map中;这一步理解起来没问题吧?
3、新节点放在Map中,存放规则是:key为老链表的当前节点,value为以链表当前节点value创建出来的新节点;这一步理解起来也不难吧?
4、再次遍历原链表,将Map中的节点取出,链接对应关系;
比如:
当前节点是7;从Map中找到key为7的value;
将节点7的下一指针节点作为Map的key找到value2;
那么value.next = value2;即可将新链表中当前节点关系关联起来;
同理:
将节点7的random指针作为Map的key找到value3;
则有value.random = value3;
根据上述思路编辑代码如下:
var copyRandomList = function(head) {
let header = head
const map = new Map();
while(header){
map.set(header,new Node(header.val))
header = header.next
}
header = head;
while(header){
const current = map.get(header)
current.next = map.get(header.next)||null;
current.random = map.get(header.random)||null;
header = header.next
}
return map.get(head)
};
时间复杂度O(n)
空间复杂度O(n)
原链表修改法
该方法是在原链表上修改得到新链表
怎么个思路呢?
如上图;
在遍历原链表过程中,生成新链表;
比如原链表为
graph LR
7 --> 13--> 11--> null
生成新链表为
graph LR
7 --> 7'--> 11-->11' --> 13--> 13'--> null
假设原链表有
graph LR
7 --> 13--> 7-->11 --> null
节点7下一节点指向13,随机节点指向11;
那么节点7'在节点7的下一位置;是不是可以根据7得到7' 那么节点7下一节点指向13,13的下一节点是13‘是不是可以将7'和13'的关系对应起来?
将关系一一对应后,将新链表从原链表分离出来即可:
根据上述思路编辑代码如下:
var copyRandomList = function(head) {
if(head === null) return;
let current = head;
//生成新的链表
while(current){
const next = current.next;
current.next = new Node(current.val)
current.next.next = next;
current = next
}
// 重新设置指针
current = head;
while(current){
const next = current.next.next;
const newCurr = current.next;
newCurr.random = current.random!==null?current.random.next:null;
current = next
}
let result = head.next;
current = head;
while(current){
const next = current.next.next;
const newCurr = current.next;
current.next = next;
newCurr.next = next!==null?next.next:null;
current = next
}
return result
};
过程比较复杂:学完比较有成就