题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
在网上看到有多种思路 这里总结一下
来源:牛客网https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba?answerType=1&f=discussion
解题思路一:
1.遍历链表 复制每个节点 将复制的节点插入原来的节点后面 如A->A1->B->B1
2.遍历链表 将老节点的特殊指针复制给新的节点
3.拆分链表 将老链表和新链表区分开
思路二:
用哈希表建立新旧链表之间节点的对应关系
迭代旧链表 建立新链表节点之间的关系
补充几个知识点:
id()函数用于获取对象的内存地址
字典是另一种可变容器模型,且可存储任意类型对象,字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
转载 https://blog.youkuaiyun.com/zhuzuwei/article/details/80554776 这里解释的很好:
3. 内存分配理解
x=3这句的执行过程并不是先获取x原来指向的对象的地址,再把内存中的值更改为3,而是新申请一段内存来存储对象3,再让x去指向对象3,所以两次id(x)的值不同。
思路二的代码:
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
head = pHead #用于循环旧链表的指针
p_head = None #用于指向表头
new_head = None #新链表的指针
old_new_list = {}
random_list = {}
while head:
node = RandomListNode(head.label) # 这里不能为head.label 因为int对象是没有random node是建立指针
node.random = head.random
old_new_list[id(head)] = id(node)#键为老链表的地址 值为新链表的地址
random_list[id(node)] = node #输入新链表的地址 输出链表的值
head = head.next
if new_head:
new_head.next = node
new_head = new_head.next
else:
new_head = node
p_head = node
new_head = p_head
while new_head:
if new_head.random != None:
new_head.random = random_list[old_new_list[id(new_head.random)]]
new_head = new_head.next
return p_head