题目:请实现函数
ComplexListNode Clone(ComplexListNode root)
,复制一个复杂链表。在复杂链表中,每个节点除了有一个next
指针指向下一个节点,还有一个sbling
指针指向链表中的任意节点或者null
。复杂链表的节点定义如下:
private static class ComplexListNode {
ComplexListNode next;
ComplexListNode sibling;
int value;
public ComplexListNode(int value) {
this.value = value;
}
}
一个复杂链表的示例如下所示
看到这个问题,很多人的解决方案是首先复制链表的每一个节点,并使用 next
指针连接起来,第二步再次遍历链表,并且逐次设置 sbling
指针。考虑该链表的长度为 N
,那么在每次设置 sbling
节点时都要搜索整个链表,搜索的时间复杂度是 $O(N)$,对于每一个节点都有这个搜索过程,所以整个时间复杂度为 $O(N^2)$。
现在我们可以考虑第二种方法,第一步仍然是根据原始链表的节点 N
创建复制的节点 N'
,并将 <N,N'>
放入到一个哈希表中,那么这样一来,第二步就不需要去搜索整个链表,只需要以 $O(1)$ 的复杂度就可以从哈希表中拿到想要的节点。这种情况就是以空间换时间,我们需要 $O(N)$ 的空间复杂度把时间复杂度从 $O(N^2)$ 降到 $O(N)$。
现在我们在考虑一种方法,首先第一步还是根据原始链表的节点 N
复制节点 N'
,并且将 N'
链接到 N
之后,如下所示
private static void cloneNodes(ComplexListNode root) { |
第二步设置复制出来的节点的 sbling
,如果节点 N
的 sbling
指针指向的是 S
,那么 N'
的 sbling
指向的就是 S.next
,如下
private static void siblingNodes(ComplexListNode root) { |
最后一步就是选择这些链表的第偶数个节点通过 next
连接起来,然后返回根节点
private static ComplexListNode reconnect(ComplexListNode root) { |
我们把上面三步接合起来,就是复制链表的完整过程
public static ComplexListNode clone(ComplexListNode root) { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Coder!
评论