题目:已知一链表,每个节点除了有一个指向下一节点的指针外,还有一随机指针指向链表中的任意节点(可能为空,也有可能为自身),请复制一个链表,要求节点的顺序以及节点上的随机指针指向的节点位置和原链表一致。
这个题目有个很巧妙的解法,可以达到O(n)的效率,其中心思想是把原始链表和复制链表先合并为一个有固定顺序的链表,然后给复制链表中每个节点的随机指针复制,最后再打断链表恢复原样。
typedef struct Node {
int nData;
Node* pNext;
Node* pRandom;
} Node;
Node* DuplicateList(Node* pSrcListHead)
{
if (pSrcListHead == NULL)
return NULL;
Node* pNode = pSrcListHead;
while (pNode != NULL)
{
Node* pNewNode = new Node;
pNewNode->nData = pNode->nData;
pNewNode->pNext = pNode->pNext;
pNewNode->pRandom = pNode->pRandom;
pNode->pNext = pNewNode;
pNode = pNewNode->pNext;
}
Node* pDestListHead = pSrcListHead->pNext;
pNode = pSrcListHead;
while (pNode != NULL)
{
pNode->pNext->pRandom = pNode->pRandom->pNext;
pNode = pNode->pNext->pNext;
}
pNode = pSrcListHead;
Node* pNode2 = pNode->pNext;
while (pNode != NULL)
{
pNode->pNext = pNode2->pNext;
pNode = pNode->pNext;
if (pNode)
pNode2->pNext = pNode->pNext;
else
pNode2->pNext = NULL;
pNode2 = pNode2->pNext;
}
return pDestListHead;
}
不过目前还未考虑到原始链表有环的情况,如果原始链表有环,则应该先求出环的入口点,然后利用上面的方法进行链表复制。
原文地址:http://hi.baidu.com/%B3%A3%D1%C5%C3%F4/blog/item/173d50ae523a0ede7dd92a63.html
分享到:
相关推荐
这样,我们就得到了两个独立的链表,一个是原始链表,另一个是复制链表,且复制链表的头部就是我们要返回的新链表头。 这个算法的时间复杂度是 O(N),因为每个节点都需要被访问一次,N 是链表的长度。空间复杂度也...
//第8题:复制链表。输入:一个无序正整数链表(输入为0表示终止)。 //输出:三行,每行一个链表,分别满足题目中的三个链表的要求。 //这道题目必须要复制链表,所以说,不能直接将输入的链表作为第一小题的输出,...
6. **复制链表**:复制一个循环链表。 7. **遍历链表**:顺序访问链表中的所有元素。 8. **截取链表**:从链表中截取出一段子链表。 ### 详细知识点解析 #### 创建循环链表 创建循环链表通常包括以下步骤: - ...
复制链表意味着创建一个新的链表,其中每个节点都与原链表中的相应节点具有相同的值。这通常分为两个步骤: 1. 遍历原链表并创建新节点:对于原链表中的每个节点,我们创建一个新节点,设置其数据字段,并将新节点的...
9. **复制链表**:创建链表的深拷贝,包括每个节点的数据和指针都要复制。 10. **链表长度**:计算链表中节点的数量,通过遍历链表直到找到空指针即可。 11. **打印链表**:按照顺序输出链表中所有节点的值,这...
3. **拆分链表**:最后,我们将原节点和复制节点分开,返回复制链表的头节点。 下面是按照上述策略实现的Python代码: ```python class Node: def __init__(self, val=None, next=None, random=None): self.val ...
// 输出复制链表 Node curr = copyHead; while (curr != null) { System.out.print("[" + curr.val + ", "); if (curr.random != null) { System.out.print(curr.random.val + "]"); } else { System.out....
复制链表的过程可能会采用迭代或递归的方法,具体取决于代码设计。关键步骤可能包括: 1. 创建一个新的链表,每个新节点对应原链表的一个节点,同时保留原链表的random指针。 2. 在遍历原链表的同时,同步更新新...
使用随机指针复制链表 给出一个链表,使得每个节点都包含一个额外的随机指针,该指针可以指向链表中的任何节点或为空。 返回列表的深层副本。 链表在输入/输出中表示为 n 个节点的列表。 每个节点都表示为一对 [val,...
复制链表通常涉及创建一个新的链表,遍历原始链表并将每个节点的数据复制到新链表中。 7. **单链表打印**: 打印链表涉及遍历链表并逐个打印节点的数据。这通常在遍历过程中调用`printf`来完成。 8. **循环链表*...
先复制链表本身,然后再处理随机指针,通过映射表找到对应的新节点。 【Q142 环形链表 II】要求找到环形链表的入口点。我们可以使用快慢指针,让快指针每次走两步,慢指针走一步。当快慢指针相遇时,已知环的周长。...
12. **链表的复制**: 复制链表意味着创建一个新的链表,其中每个新节点都包含原链表相应节点的值。这需要为每个原始节点创建新的副本节点,并更新指针关系。 以上12个操作是理解和操作C语言单向链表的基础。熟练...
5. **复制链表**:创建原链表的一个深度复制。 学习链表不仅有助于提升编程技能,也是解决复杂问题的基础,如图的深度优先搜索(DFS)和广度优先搜索(BFS),以及数据流中的中位数计算等问题。通过"链表试题可以...
12. **复制链表**:创建链表的深度拷贝,即每个原链表节点都有一个对应的副本节点,且保持原有的链接关系。 13. **判断链表是否有环**:使用快慢指针(Floyd's Cycle-Finding Algorithm)来检测链表中是否存在环。 ...
复制链表涉及创建新的节点并复制原链表的每个节点数据,同时更新新链表中节点的指针域。 10. **内存管理**: 使用链表时需要注意内存管理,尤其是在插入和删除节点后,确保正确地释放不再使用的内存,防止内存...
首先,参数为一个pHead,要求我们能够复制链表。 我们先来看看其他大佬的做法(转自牛友chancy) 逻辑很强,值得学习。 /* *解题思路: *1、遍历链表,复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面; *2...
9. **链表的复制**:复制链表包括复制节点和复制指针关系,可以采用深拷贝的方式实现。 这些基本操作构成了链表操作的基础,理解和掌握这些概念对于理解和设计复杂的算法至关重要。在实际编程中,链表常被用于实现...
复制链表可以通过`list<int> L3(L2);`实现,而`list<int> L4(L0.begin(), L0.end());`则用于创建一个与`L0`相同元素的链表。 `std::list`提供了多种操作方法: 1. `assign()`方法用于分配新的元素序列,例如`L1....
复制链表涉及到更复杂的数据结构理解,特别是当链表节点中包含指向其他节点的随机指针时。 数组的操作包括了基础的元素访问、插入、删除等,还涉及到子数组(连续的元素序列)以及排序数组的处理。数组的操作相对...
在实际应用中,删除节点和复制链表的实现可能需要更复杂的逻辑,例如查找待删除节点的位置,或者创建新的节点并将数据逐个复制。这些操作都需要考虑到链表为空或只有一个节点的特殊情况。 总之,单链表是数据结构中...