
题目难度: 中等web
原题连接[1]算法
今天继续更新剑指 offer 系列, 这道题实现起来并不难, 但须要必定的思考, 你们能够先尝试本身想一想如何解决微信
老样子晚上 6 点 45 分准时更新公众号 每日精选算法题, 你们记得关注哦~ 另外在公众号里回复 offer 就能看到剑指 offer 系列当前连载的全部文章了dom
题目描述
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每一个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。编辑器
-
-10000 <= Node.val <= 10000 -
Node.random 为空(null)或指向链表中的节点。 -
节点数目不超过 1000 。
题目样例
示例
输入

head = [[7,null],[13,0],[11,4],[10,2],[1,0]]函数
输出
[[7,null],[13,0],[11,4],[10,2],[1,0]]flex
题目思考
-
如何处理 random 指针?
解决方案
思路
-
若是只有 next 指针的话很简单, 咱们只须要对每一个节点新建一个相同值的节点, 并保持指向关系, 逐个遍历过去便可 -
如今多了个 random 指针, 想要定位新的指向的节点, 一个比较天然的想法就是额外维护一个老节点到新节点的映射关系, 能够用字典来实现 -
第一遍遍历, 就只关注 next 部分, 并创建好映射关系 -
第二遍遍历, 考虑 random 部分, 找到对应的新链表的节点, 而后当前节点的 random 指针指向它便可
复杂度
-
时间复杂度 O(N)
-
每一个节点只须要遍历两次 -
空间复杂度 O(N)
-
额外须要一个字典
代码
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
maps = {}
# 第一遍遍历, 创建新的链表, 以及老节点到新节点的映射关系
copyHead = Node(head.val)
origin, copy = head, copyHead
maps[origin] = copy
while origin.next:
# 新建下一个节点, 并创建next关系
copy.next = Node(origin.next.val)
origin = origin.next
copy = copy.next
maps[origin] = copy
# 第二遍遍历, 处理random指针部分
origin, copy = head, copyHead
while origin:
if origin.random:
# 若是老节点random指针指向非空的话, 就将当前新节点也指向随机节点对应的新节点
copy.random = maps[origin.random]
origin = origin.next
copy = copy.next
return copyHead
参考资料
原题连接: https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/spa




本文分享自微信公众号 - 每日精选算法题(DailyAlgorithm)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。.net