原题链接:138. 随机链表的复制 - 力扣(LeetCode)
这道题的意思:需要创建一个新链表,并且复制原链表的节点,返回的是新链表的头节点。
但是这里有一个关键点,链表的random指针指向的节点是一个随机节点,也可能指向NULL,因为要返回的是全新的的链表,链表中的每个节点都是需要去申请来的,所以,原链表节点中的random指针指向的节点,与新链表的节点中的random指向的节点是毫无关联的。
这里一定要理解,新链表的地址都是通过malloc申请,malloc申请的地址都是随机值,唯一相同的只有他们的next指针都是指向下一个链表,所以新链表与原链表是毫无关联,不能单纯的通过原链表的random节点去匹配新链表的random节点
可能有读者会有疑惑,那可不可以直接遍历原链表节点的val值,让原链表random指向的节点中的val值去匹配新链表节点random指针的指向的节点中val值。那么这里再列举一个图
那么从图可以看出,如果只是判断val值的话,当出现两个节点中val值都一样的时候,13的random节点就不知道该指向哪一个。
小编在这里提供一种解题方法这个方法分三步走:
第一步:将每个拷贝的节点都放置在原节点后
我们将每一个拷贝节点都尾插在每个原节点的后面,改变原节点next指针指向,与拷贝节点next指针的指向,这里先不要去动拷贝节点的random指针。
第二步:观察原节点的random与拷贝节点的random的关系
这里请认真观察原节点->random与原节点->random->next之间的关系,例如:原13节点->random=原7节点,原13节点->random->next=复制节点的7节点,再比如原11节点->random=原1节点,原11节点->random->next=复制节点的1节点。
由此可以得出结论:拷贝节点->random=原节点->random->next
第三步:解拷贝节点并还原源节点:
现在我们已经将拷贝节点的random指针进行了正确指向,接下来只需要将每个拷贝节节点组成新的链表,并将原节点进行恢复,那么这道题就解开了。
以下是答案代码: