您的位置:首页 > Web前端

【剑指Offer】复杂链表的复制

2018-01-26 11:18 573 查看

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

题目分析

如果是普通链表,那么将原链表遍历一遍,创建出新链表即可。但是这个链表中每个节点中有一个指向任意结点的指针,这就增加了实现的难度。对于这样的问题,有三种思路。

1. 将原链表复制后,对于新链表中的每一个结点,在原链表中寻找其特殊指针指向的结点,然后在新链表中找到,并指向那个结点。时间复杂度为O(n^2)。

2. 将原链表的结点以及新链表的结点一一对应的存储在Hash表中,这样通过两次遍历链表的操作即可将链表复制。时间复杂度为O(n),空间复杂度为O(n)。

3. 将原链表的结点复制后,插入到原结点后面,这样复制完之后就会发现,新链表中每一个节点特殊指针即为原链表结点特殊指针后面的那个结点,这样的时间复杂度为O(n)。

代码实现



RandomListNode* RandomList::cloneByHashTable(RandomListNode* pHead){

if (pHead == NULL)

{

return NULL;

}

// 定义一个hash表
unordered_multimap<RandomListNode*, RandomListNode*> table;
// 开辟一个头结点
RandomListNode* pCloneHead = new RandomListNode(0);
pCloneHead->next = NULL;
pCloneHead->random = NULL;

//将头节
4000
点放入table中
table.insert(make_pair(pHead,pCloneHead));

// 设置操作指针
RandomListNode* pNode = pHead->next;
RandomListNode*pCloneNode = pCloneHead;

// 第一遍,先简单复制链表
while (pNode != NULL)
{
RandomListNode* pCloneTail = new RandomListNode(pNode->label);
pCloneTail->next = pNode->next;
pCloneTail->random = NULL;

// 将复制的节点链接到复制链表的尾部
pCloneNode->next = pCloneTail;
// 更新当前结点
pCloneNode = pCloneTail;

// 将新的对应关系插入到Hash表
table.insert(make_pair(pNode,pCloneTail));

// 移动原链表操作指针
pNode = pNode->next;
}

// 需从头设置特殊指针,重新设置操作指针
pNode = pHead;
pCloneNode = pCloneHead;

while (pNode != NULL){
// 如果存在特殊指针,则设置之
if (pNode->random != NULL)
{
pCloneNode->random = table.find(pNode->random)->second;
}
// 移动原链表以及克隆链表
pNode = pNode->next;
pCloneNode = pCloneNode->next;
}
return pCloneHead;


}

class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;

RandomListNode(int label) {
this.label = label;
}
}

public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
copyList(pHead);
setSibling(pHead);
return disconnectedList(pHead);
}

// 将复制后的结点放在原链表结点的尾部
private void copyList(RandomListNode head){
if(head == null)
return;
RandomListNode node = head;
while(node != null){
RandomListNode copyNode = new RandomListNode(node.label);
copyNode.next = node.next;
copyNode.random = null;

node.next = copyNode;
node = copyNode.next;
}
}

// 将链表中复制后的结点的random属性设置好
private void setSibling(RandomListNode head){
if(head == null)
return;
RandomListNode node = head;
while(node != null){
RandomListNode copyNode = node.next;
if(node.random != null){
copyNode.random = node.random.next;
}
node = copyNode.next;
}
}

private RandomListNode disconnectedList(RandomListNode head){
RandomListNode node = head;
RandomListNode copyHead = null;
RandomListNode copyNode = null;
if(node != null){
copyHead = node.next;
copyNode = node.next;

node.next = copyNode.next;
node = node.next;
}

while(node != null){
copyNode.next = node.next;
copyNode = copyNode.next;

node.next = copyNode.next;
node = node.next;
}
return copyHead;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: