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

LeetCode:Copy List with Random Pointer

2013-10-24 23:02 519 查看
题目地址:here

题目大意:深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向字符串中的某个节点或者为空。

节点定义为:

struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};

假设原始链表如下,细线表示next指针,粗线表示random指针,没有画出的指针均指向NULL:



算法1:我们在构建新链表的节点时,保存原始链表的next指针映射关系,并把指针做如下变化(蓝色为原始链表节点,紫红色为新链表节点):



然后在上图的基础上进行如下两步

1、构建新链表的random指针:比如new1->random = new1->random->random->next, new2->random = NULL, new3-random = NULL, new4->random = new4->random->random->next

2、恢复原始链表:根据最开始保存的原始链表next指针映射关系恢复原始链表

该算法时间空间复杂度均为O(N)

算法2:该算法更为巧妙,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:



同理分两步

1、构建新节点random指针:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next

2、恢复原始链表以及构建新链表:例如old1->next = old1->next->next, new1->next = new1->next->next

该算法时间复杂度O(N),空间复杂度O(1)

下面分别为算法1和算法2代码:

class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head)
{
// Note: The Solution object is instantiated only once and is reused by each test case.
if(head == NULL)return NULL;
std::map<RandomListNode *,RandomListNode *> oldlistMap;
RandomListNode *result = new RandomListNode(head->label) ;
RandomListNode *pold = head, *pnew = result;
pnew->random = pold;
//pold->next = pnew;
RandomListNode* poldPre = pold, *pnewPre = pnew;
while(pold->next != NULL)
{
//保存old list的next指针
oldlistMap.insert(std::map<RandomListNode*,
RandomListNode*>::value_type(pold, pold->next));
pold = pold->next;
poldPre->next = pnew;
pnew = new RandomListNode(pold->label);
pnewPre->next = pnew;
pnew->random = pold;

poldPre = pold;
pnewPre = pnew;
}
pold->next = pnew;//设置old list最后一个节点

//设置new list的random指针
pnew = result;
while(pnew != NULL)
{
if(pnew->random->random)
pnew->random = pnew->random->random->next;
else pnew->random = NULL;
pnew = pnew->next;
}
//恢复old list的next指针
pold = head;
for(int i = 1; i <= oldlistMap.size(); i++)
{
pold->next = oldlistMap[pold];
pold = pold->next;
}
pold->next = NULL;//old list 最后一个节点

return result;
}
};


class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head)
{
// Note: The Solution object is instantiated only once and is reused by each test case.
if(head == NULL)return NULL;
RandomListNode *result = NULL;
RandomListNode *pold = head, *pnew = result, *poldNext = NULL;
do
{
poldNext = pold->next;
pnew = new RandomListNode(pold->label);
pold->next = pnew;
pnew->next = poldNext;

if(result == NULL)
result = pnew;
pold = poldNext;
}while(pold);
//设置new list的random指针
pold = head;
while(pold)
{
if(pold->random)
pold->next->random = pold->random->next;
pold = pold->next->next;
}
//恢复old list 和new list
pold = head;
pnew = result;
while(pnew->next)
{
pold->next = pnew->next;
pold = pold->next;
pnew->next = pold->next;
pnew = pnew->next;
}
pold->next = NULL;
pnew->next = NULL;
return result;
}
};


【版权声明】转载请注明出处:/article/4879617.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: