138. 复制带随机指针的链表 回溯 结合133克隆图一起看

题意:给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的深拷贝
深拷贝用回溯方法

回溯

回溯算法的第一想法是将链表想象成一张图。链表中每个节点都有2个指针(图中的边)。因为随机指针给图结构添加了随机性,所以我们可能会访问相同的节点多次,这样就形成了环。
此方法中,我们只需要遍历整个图并拷贝它。拷贝的意思是每当遇到一个新的未访问过的节点,你都需要创造一个新的节点。遍历按照深度优先进行。我们需要在回溯的过程中记录已经访问过的节点,否则因为随机指针的存在我们可能会产生死循环。我们针对两种情况进行回溯调用:一个顺着 random 指针调用,另一个沿着 next 指针调用

class Solution:
    def __init__(self):
        self.visitedHash={}
    def copyRandomList(self,head):
        if head==None:
            return
        if head in self.visitedHash: #当我们遍历到某个点时,如果我们已经有了当前节点的一个拷贝,我们不需要重复进行拷贝。
            return self.visitedHash[head]
        node = Node(head.val,None,None) #如果我们还没拷贝过当前节点,我们创造一个新的节点,并把该节点放到已访问字典中
        self.visitedHash[head]=node
        node.next=self.copyRandomList(head.next) #我们针对两种情况进行回溯调用:一个顺着 random 指针调用,另一个沿着 next 指针调用
        node.random=self.copyRandomList(head.random)
        return node

时间空间复杂度O(n)

还有一个方法是复制节点,指针关系复杂,但是很巧妙,可以学习一下,但不具有推广,空间复杂度O(1)

class Solution:
    def copyRandomList(self,head):
        if not head:
            return head
        ptr = head
        while ptr:
            new_node=Node(ptr.val,None,None)
            new_node.next=ptr.next  #A'->B
            ptr.next=new_node # A->A'
            ptr=new_node.next #ptr移位下一个节点,继续循环;最后生成AA'BB'CC'
        
        ptr = head
        while ptr:
            ptr.next.random=ptr.random.next if ptr.random else None #A'的random = A的randomC的nextC'
            ptr=ptr.next.next
        ptr_old=head
        ptr_new=head.next
        head_new=head.next###注意链表题亮点!
        while ptr_old:
            ptr_old.next=ptr_old.next.next
            ptr_new.next=ptr_new.next.next if ptr_new.next else None
            ptr_old=ptr_old.next
            ptr_new=ptr_new.next
        return head_new###注意链表题亮点!
发布了79 篇原创文章 · 获赞 0 · 访问量 1530
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览