📌  相关文章
📜  克隆带有下一个和随机指针的链表 |设置 1

📅  最后修改于: 2022-05-13 01:57:45.344000             🧑  作者: Mango

克隆带有下一个和随机指针的链表 |设置 1

你会得到一个双链表,每个节点的一个指针指向下一个节点,就像在单链表中一样。然而,第二个指针可以指向列表中的任何节点,而不仅仅是前一个节点。现在在 O(n) 时间内编写一个程序来复制这个列表。也就是说,编写一个程序来创建此列表的副本。

让我们称第二个指针为仲裁指针,因为它可以指向链表中的任意节点。

ArbitLinked List1

图1

任意指针显示为红色,下一个指针显示为黑色



方法 1(使用 O(n) 额外空间)
该方法首先将(原始列表的)下一个和任意映射存储在一个数组中,然后修改原始链表(创建副本),创建一个副本。并最终恢复原始列表。

1)使用next指针在复制链表中创建所有节点。
2) 存储原始链表的节点及其下一个指针映射。
3) 将原链表中所有节点的next指针改为指向复制链表中对应的节点。
下图显示了经过上述 3 个步骤后两个链表的状态。红色箭头显示仲裁指针,黑色箭头显示下一个指针。

ArbitLinked List2

图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 现场工作专业课程学生竞争性编程现场课程。