剑指 Offer 35. 复杂链表的复制(深拷贝/BFS/DFS)

  • 题目描述

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 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。

  • 解法一:DFS深度优先

这道题的考点在链表的深拷贝和浅拷贝。

在Python中其实可以用一句话就实现深拷贝

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        return copy.deepcopy(head)

 dfs其实就是递归求解。

首先我们先判断递归结束条件:当此时节点为空结束,返回None

调用递归:创建新节点copy,copy的next为递归head的next节点,copy的random为递归head的random节点,返回copy即可。

附加条件:当递归调用某个节点已经被拷贝,即已经出现在visited这个hash表中(说明之前已经拷贝过),则不需要拷贝,直接返回这个节点即可。

"""
# 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':
        
        def recur(head):
            if not head:
                return
            if head in visitisted:
                return visitisted[head]
            copy = Node(head.val, None, None)
            visitisted[head] = copy
            copy.next = recur(head.next)
            copy.random = recur(head.random)
            return copy
        visitisted = {}
        return recur(head)
  • 解法二:BFS广度优先搜索

广度优先我们通常都是用队列实现的。

1.我们首先创建hash表保存已经拷贝的节点({原节点:拷贝节点})

2.创建队列,并将head入队

3.当队列不为空,弹出一个节点,如果该节点的next没有被拷贝,则拷贝该节点的next节点,如果该节点的random节点没被拷贝过,则拷贝random节点

"""
# 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
"""
from collections import deque
class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        '''
        bfs解法:队列
        '''
        if not head:
            return 
        res = {}
        dq = deque()
        dq.append(head)
        copy = Node(head.val, None, None)
        res[head] = copy

        while dq:
            tmp = dq.pop()
            if tmp.next and tmp.next not in res:
                res[tmp.next] = Node(tmp.next.val, None, None)
                # res[tmp.next] = tmp.next
                dq.append(tmp.next)
            if tmp.random and tmp.random not in res:
                res[tmp.random] = Node(tmp.random.val, None, None)
                # res[tmp.random] = tmp.random
                dq.append(tmp.random)
            res[tmp].next = res.get(tmp.next)
            res[tmp].random = res.get(tmp.random)
        return copy

时间复杂度:O(N)

空间复杂度:O(N)

原文地址:https://www.cnblogs.com/yeshengCqupt/p/13714749.html