【leetcode - 138】复制带随机指针的链表 medium

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

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

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

"""
# 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':
        #选择最简单的特殊情况#
        if not head:
            return head
        #链表需要保存head,所以初始化一个一样的node用来遍历
        #下面means指向同一地址
        pre = head 
        #考虑在原始节点后生成新节点,旧节点指向新节点
        while pre:
            #clone node
            new = Node(pre.val,None,None)
            #新节点下一个指向源节点的下一个,源节点下一个指向新节点,然后move on源节点到新节点下一个
            new.next = pre.next
            pre.next = new
            pre = new.next
        #考虑random节点的指向
        #从原始head开始
        pre = head
        while pre:
            pre.next.random = pre.random.next if pre.random else None
            #move on源节点去下一个
            pre = pre.next.next
        #现在已经构造完新的链表啦
        #选择新链表
        pre = head
        new_list = pre.next
        new_head = pre.next
        while pre:
            pre.next = pre.next.next
            new_list.next = new_list.next.next if new_list.next else None
            pre = pre.next
            new_list = new_list.next
        return new_head

还有种思维方式是先通过遍历和指针把现有的node对应关系建立,再通过这个hashmap把新的链表的next和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
"""

class Solution:
    #构建一个hashmap
    def __init__(self):
        self.visited = {}
    #如果hashmap中没有,就新建,如果有,就返回当前node
    def getclonednode(self,node):
        if node:
            if node in self.visited:
                return self.visited[node]
            else:
                self.visited[node] = Node(node.val,None,None)
                return self.visited[node]
        return None
    #对应拷贝
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head:
            return head
        newhead = Node(head.val,None,None)
        newlist = newhead
        self.visited[head] = newhead
        while head:
            newhead.next = self.getclonednode(head.next)
            newhead.random = self.getclonednode(head.random)
            head = head.next
            newhead = newhead.next
        return newlist

 

posted @ 2020-10-16 15:13  Akassy  阅读(88)  评论(0)    收藏  举报