Day25:复杂链表的复制

时间:2022-07-24
本文章向大家介绍Day25:复杂链表的复制,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

剑指Offer_编程题——复杂链表的复制

题目描述:

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。 注意:输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空。

具体要求:

时间限制: C/C++ 1秒,其他语言2秒 空间限制: C/C++32M,其他语言64M

具体思路:

第一步:在原节点后面创建一个相同的节点,其实就是链表插入的过程。具体过程如下图:

第二步,遍历克隆的节点,让它的random等于原来的随机的next,也就是下一个节点

第三步,遍历整个克隆完毕的链表,让当前点指向下面隔一个的点

具体思路用Java实现如下:

public class Solution{
	public RandomListNode Clone(RandomListNode pHead){
	while (pHead == null){
		return null;
		}	
		RandomListNode cur = pHead;
		while(cur != null){
			RandomListNode clone1 = new RandomListNode(cur.label);
			clone1.next = cur.next;
			cur.next = clone1;
			cur = clone1.next;
		}
			cur = pHead;
			while(cur != null){
				RandomListNode clone2 = cur.next;
				if(cur.random != null) {
					clone2.random = cur.random.next;
				}
				   cur = clone2.next;
			}
			cur = pHead;
			RandomListNode resultHead = cur.next;
			while(cur.next != null){
				RandomListNode clone3 = cur.next;
				cur.next = clone3.next;
				cur = clone3;
			}
			return resultHead;
	}
}

代码通过示意图如图所示:

  正如前面提到一样,牛客网已经为我们定义了节点,不需要我们重复定义,但是在自己的本地编译器中,我们需要定义节点RandomListNode的类,具体实现如下:

public class RandomListNode{
	int label;
	RandomListNode next = null;
	RandomListNode random = null;
	RandomListNode(int label)
	{
		this.label = label;
	}
}

用python实现该思路:

class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        self.cloneNodes(pHead)
        self.connectSiblingNodes(pHead)
        return self.reconnectNodes(pHead)

    def cloneNodes(self, pHead):
        pNode = pHead
        while pNode:
            pCloned = RandomListNode(pNode.label)
            pCloned.next = pNode.next
            pNode.next = pCloned
            pNode = pCloned.next

    def connectSiblingNodes(self, pHead):
        pNode = pHead
        while pNode:
            pclone = pNode.next
            if pNode.random:
                pclone.random = pNode.random.next
            pNode = pclone.next

    def reconnectNodes(self, pHead):
        pNode = pHead
        pCloneHead = None
        pCloneNode = None
        if pNode:
            pCloneHead = pCloneNode = pNode.next
            pNode.next = pCloneNode.next
            pNode = pNode.next
        while pNode:
            pCloneNode.next, pCloneNode = pNode.next, pCloneNode.next
            pNode.next, pNode = pCloneNode.next, pNode.next
        return pCloneHead

代码效果图如图所示:

用python实现该链表结构:

class RandomListNode{
	def __init__(self, x):
		self.label = x
		self.next = None
		self.random = None
}

总结

  本道题主要考察复杂链表的复制,本题主要用到的核心算法就是分而治之的思想。并且我们通过一个案例来让我们更加明白这个题的要求,并且分别用java和python将其实现,其实本题是通过一个给出一种新型链表的定义,让我们打印出其表头。这是将链表、分而治之以及我们分析问题的实际能力相结合。当然我们也要掌握数据结构相关的知识,只有这样,才能遇到综合性问题做到融会贯通,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!

参考文献

[1] IDEA_TEYU_1112 [2] 负雪明烛