【牛客剑指offer刷题】:Python:25.复杂链表的复制

复杂链表的复制

时间限制:1秒 空间限制:32768K 热度指数:329252
本题知识点: 链表
算法知识视频讲解

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

法1.递归法

# -*- coding:utf-8 -*-
# class RandomListNode:
#     def __init__(self, x):
#         self.label = x
#         self.next = None
#         self.random = None
class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        # write code here
        if not pHead:
            return 
        newNode = RandomListNode(pHead.label)
        newNode.random = pHead.random  
        # 注意:这里的random不用递归
        newNode.next = self.Clone(pHead.next)
        return newNode

法2.哈希表法

        # 法2.哈希表法
# -*- coding:utf-8 -*-
# class RandomListNode:
#     def __init__(self, x):
#         self.label = x
#         self.next = None
#         self.random = None
class Solution:
     #返回 RandomListNode
    def Clone(self, pHead):
        # write code here
        nodeList = []     # 存放各个节点
        randomList = []   # 存放各个节点指向的random节点,没有则为None
        labelList = []    # 存放各个节点的值
        
        while pHead:
            randomList.append(pHead.random)
            nodeList.append(pHead)
            labelList.append(pHead.label)
            pHead = pHead.next
        
        # random 节点的索引,如果没有则为-1
        labelIndexList = map(lambda c: nodeList.index(c) if c else -1, randomList)
        
        dummy = RandomListNode(0)
        pre = dummy
        #节点列表,只要把这些节点的random设置好,顺序串起来就ok了。
        nodeList = map(lambda c:RandomListNode(c), labelList)
        #把每个节点的random绑定好,根据对应的index来绑定
        for i in range(len(nodeList)):
            if labelIndexList[i] != -1:
                nodeList[i].random = nodeList[labelIndexList[i]]
        for i in nodeList:
            pre.next = i
            pre = pre.next
        return dummy.next

法3.三步法

解析

图4.8 是一个含有5 个结点的复杂链表。图中实线箭头表示next 指针,虚线箭头表示随机引用。为简单起见,指向null 的指针没有画出。
【牛客剑指offer刷题】:Python:25.复杂链表的复制_第1张图片

  1. 把复制的结点链接在原始链表的每一对应结点后面

    【牛客剑指offer刷题】:Python:25.复杂链表的复制_第2张图片

  2. 把复制的结点的random指针指向被复制结点的random指针的下一个结点
    【牛客剑指offer刷题】:Python:25.复杂链表的复制_第3张图片

  3. 拆分成两个链表,奇数位置为原链表,偶数位置为复制链表,注意复制链表的最后一个结点的next指针不能跟原链表指向同一个空结点None,next指针要重新赋值None(判定程序会认定你没有完成复制)
    【牛客剑指offer刷题】:Python:25.复杂链表的复制_第4张图片

代码

    # 法3.三步法
class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        # write code here
        if not pHead:
            return None
        
      
        # 1.copy phead
        dummy = pHead
        while dummy:
            dummyNext = dummy.next
            copyNode = RandomListNode(dummy.label)
            copyNode.next = dummyNext
            
            dummy.next = copyNode
            dummy = dummyNext
        
        # 2.random to random
        dummy = pHead
        while dummy:
            dummyRandom = dummy.random
            copyNode = dummy.next
            if dummyRandom:
                copyNode.random = dummyRandom.next
            dummy = copyNode.next
        
        # 3.split linked list
        dummy = pHead
        copyHead = pHead.next
        while dummy:
            copyNode = dummy.next
            dummyNext = copyNode.next
            dummy.next = dummyNext
            if dummyNext:
                copyNode.next = dummyNext.next
            else:
                copyNode.next = None
            dummy = dummyNext
        return copyHead

链接:https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba
来源:牛客网

你可能感兴趣的:(牛客网剑指offer刷题,Python刷剑指offer)