克隆带有下一个和随机指针的链表 |设置 1
你会得到一个双链表,每个节点的一个指针指向下一个节点,就像在单链表中一样。然而,第二个指针可以指向列表中的任何节点,而不仅仅是前一个节点。现在在 O(n) 时间内编写一个程序来复制这个列表。也就是说,编写一个程序来创建此列表的副本。
让我们称第二个指针为仲裁指针,因为它可以指向链表中的任意节点。
图1
任意指针显示为红色,下一个指针显示为黑色
方法 1(使用 O(n) 额外空间)
该方法首先将(原始列表的)下一个和任意映射存储在一个数组中,然后修改原始链表(创建副本),创建一个副本。并最终恢复原始列表。
1)使用next指针在复制链表中创建所有节点。
2) 存储原始链表的节点及其下一个指针映射。
3) 将原链表中所有节点的next指针改为指向复制链表中对应的节点。
下图显示了经过上述 3 个步骤后两个链表的状态。红色箭头显示仲裁指针,黑色箭头显示下一个指针。
图2
4) 将复制链表中所有节点的仲裁指针改为指向原链表中对应的节点。
5) 现在在复制链表中构造arbit 指针如下所示,并恢复原始链表中节点的next 指针。
copy_list_node->arbit =
copy_list_node->arbit->arbit->next;
copy_list_node = copy_list_node->next;
6)从存储的映射中恢复原始链表中的下一个指针(在步骤2中)。
时间复杂度:O(n)
辅助空间:O(n)
方法 2(使用恒定的额外空间)
感谢 Saravanan Mani 提供此解决方案。此解决方案使用恒定空间。
1) 创建节点 1 的副本并将其插入到原始链表中的节点 1 和节点 2 之间,创建 2 的副本并将其插入到 2 和 3 之间.. 以这种方式继续,在第 N 个节点之后添加 N 的副本
2)现在以这种方式复制任意链接
original->next->arbitrary = original->arbitrary->next; /*TRAVERSE
TWO NODES*/
这是有效的,因为 original->next 只不过是 original 的副本,而 Original->arbitrary->next 只不过是任意的副本。
3)现在以这种方式在单个循环中恢复原始和复制链表。
original->next = original->next->next;
copy->next = copy->next->next;
4) 确保 original->next 的最后一个元素为 NULL。
有关此方法的实现,请参阅下面的帖子。
在 O(1) 空间中克隆一个带有 next 和随机指针的链表
时间复杂度:O(n)
辅助空间:O(1)
有关基于哈希的实现,请参阅以下帖子。
克隆带有下一个和随机指针的链表 | 2套
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。