您的位置:首页 > 运维架构

附有随机结点指针的链表的深度拷贝 Copy List with Random Pointer

2014-03-13 18:27 417 查看
问题:

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

思路:

方法一:最先想到的办法是借助hash保存旧结点到新结点的映射。这样在填充新节点随机结点指针字段的时候能直接映射过去。该方法用了辅助空间O(n)。

/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
*     int label;
*     RandomListNode *next, *random;
*     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:

// Time complexity : O(n)
// Space complexity : O(n)
RandomListNode* copyRandomList(RandomListNode *head)
{
if(head == NULL)
return NULL;

map<RandomListNode*, RandomListNode*> m;
// Build new list
// 先建首节点,每个节点都复制label和random,并添加旧地址到新地址的映射
RandomListNode *newlist = new RandomListNode(head->label);
newlist->random = head->random;
m.insert(pair<RandomListNode*, RandomListNode*>(head, newlist));

RandomListNode *p = head->next, *q = newlist;
while(p != NULL)
{
q->next = new RandomListNode(p->label);
q = q->next;
q->random = p->random;
m.insert(pair<RandomListNode*, RandomListNode*>(p, q));
p = p->next;
}

// Fill rand-link
q = newlist;
while(q != NULL)
{
q->random = m[q->random];
q = q->next;
}
return newlist;
}

};

方法二:不使用辅助空间的高效方法。三步走:1、把复制的每个新节点插入到旧结点的后面。2、这样在填写随机指针字段的时候可以直接查看旧结点的后面。3、新旧链表拆解开。旧结点要有良心的恢复成原样。

// Time complexity : O(n)
// Space complexity : O(1)
RandomListNode* copyRandomList(RandomListNode *head)
{
if(head == NULL)
return NULL;
RandomListNode *p ,*q;
//Step one: 插入新节点
p = head;
while(p != NULL)
{
q = new RandomListNode(p->label);
q->next = p->next;
p->next = q;
p = p->next->next; //右移别忘记
}

//Step two: 填写随机字段
p = head;
while(p != NULL)
{
if(p->random == NULL) //随机指针可能是NULL
p->next->random = NULL;
else
p->next->random = p->random->next;
p = p->next->next;
}

//Step three: 拆解链表,恢复原链表,拆接出新链表
p = head;
q = head->next;
RandomListNode * newlist = q;
while(q->next != NULL)
{
p->next = q->next;
q->next = q->next->next;
p = p->next;
q = q->next;
}
p->next = NULL;
return newlist;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐