一、包含随机指针的单链表的深度拷贝
最近遇到一道很有趣的题目:给定每个节点都包含随机指针的单链表,问如何深度拷贝这个单链表?
类似的单链表如图所示:
总结了下看到的答案,大致可分为三种方法:
1、暴力复制(很朴素的方法)
因为随机指针可能指向当前节点之后的节点,所以考虑分两步来做。
第一步遍历单链表,拷贝节点及节点的next指针,不考虑节点的random指针。结束后得到一个新的单链表。
第二步遍历原单链表,如果当前访问节点A有random指针指向节点B,则在新的单链表中找到相应的节点AA以及random所指向节点BB,令AA->random = BB。
时间复杂度:O(N2)
2、通过节点映射关系实现深度拷贝
考虑第一种方法可以发现时间主要耗费在复制random指针的过程中需要查找相应的节点,因此可想到如果能够建立原单链表与新单链表节点之间的映射关系,那么只需遍历一次即可完成random指针的拷贝。详细步骤如下:
第一步遍历单链表,拷贝节点及节点的next指针,不考虑节点的random指针。结束后得到一个新的单链表。
第二步遍历原单链表,如果当前访问节点A有random指针指向节点B,则令map[A]->random = map[B]即可。
故只需要两次遍历,时间复杂度为O(2N)
代码如下:
|
|
3、在原单链表上插入节点并删除实现深度拷贝
基本思想同2相似,通过减少查找节点的时间来提高效率。在原单链表中每个节点之后插入一个新节点,如下图所示:
当拷贝random指针时就可以通过以下代码实现。
|
|
其实这也是一种特殊的节点映射关系 。故时间复杂度同2为O(2N)
代码如下:
|
|
二、包含随机指针的二叉树深度拷贝
同上,这里也有三种对应的方法。
1、暴力复制(OTZ)
就是暴力。。。时间复杂度为O(N2)
2、通过节点映射关系实现深度拷贝
同单链表中节点建立映射关系一样,这里的时间复杂度同样为O(2N)。
具体代码如下:
|
|
3、在原二叉树上插入新节点后再删除
思想同单链表操作一样,但这里要注意节点间的相对关系,在创建新节点时要正确建立该节点与父节点原左右孩子的关系。具体如图示:
具体代码如下:
|
|