Leetcode 138. 复制带随机指针的链表

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的 深拷贝。 

我们用一个由 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。

 

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

**难度**: Medium

**标签**: 哈希表、 链表、


# -*- coding: utf-8 -*-
# @Author  : LG

"""
执行用时:40 ms, 在所有 Python3 提交中击败了95.03% 的用户
内存消耗:14.9 MB, 在所有 Python3 提交中击败了5.26% 的用户

解题思路:
    回溯
    使用head记录已经访问过的节点,和新创建的对应节点
    实现详情见代码注释
"""
class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':

        def backtrack(head, visited):
            if head == None:    # None时,返回None
                return head

            if head in visited: # 如果head访问过了,返回对应的创建的新节点
                return visited[head]

            else:
                node = Node(head.val)   # 没有访问过,创新新节点
                visited[head] = node    # 将新创建的节点,与head绑定,记录到以访问
                node.next = backtrack(head.next, visited)   # 访问head节点的next
                node.random = backtrack(head.random, visited)   # 访问head节点的random
                return node

        node = backtrack(head, {})
        return node