题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
概念
复杂链表示例:方法一
可以分为两步来完成:
1、复制原始链表上的每一个结点,并用next链接起来;
2、设置每个结点的random 指针:由于链表中节点的random指针指向的节点可能在该节点之前,也可能在该节点之后,需要从头到尾的遍历链表来进行查找,然后连接起来,所以时间复杂度是O(N^2)。
方法二
方法一的时间花费主要在定位结点的random上,故我们可以对此优化:用空间换时间。方法还是可以分为两步:
1、复制原始链表上的每一个结点,并用next链接起来,同时创建一个map映射表:<N,N'>(原始结点,复制的结点),将两个链表中的节点映射起来,从而便于后续random指针的设置。
2、设置每个结点的random 指针:由于已经使用map结构将两个链表中的节点进行了映射,可以很方便的找到random指针应该指向的节点。用O(n)的空间消耗把时间复杂度由O(N^2)降到了O(n)。
对应的代码如下:
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if( pHead == NULL )
return NULL;
unordered_map<RandomListNode*,RandomListNode*> record;
RandomListNode* res = new RandomListNode(pHead->label);
RandomListNode* p1 = pHead->next;
RandomListNode* p2 = res;
while( p1 )
{
RandomListNode* temp = new RandomListNode(p1->label);
p2->next = temp;
record.insert( make_pair(p1,temp) );
p1 = p1->next;
p2 = temp;
}
p1 = pHead;
p2 = res;
while( p1 )
{
if( p1->random )
p2->random = record[p1->random];
p1 = p1->next;
p2 = p2->next;
}
return res;
}
};
方法三
方法可以分为三步,以下图中的链表为例:
1、复制原始链表上的每一个结点N,创建对应的N’,并把N’放在N之后。如下图:
2、设置每个结点的random 指针。如果原始链表上的结点N的random指向S,则对应的复制结点N’(即节点N的next)的random指向S’(节点S的next)。如下图:
3、将长链表拆分成两个链表:把奇数位置的结点用pNext连接起来的就是原始链表,把偶数位置的结点通过pNext连接起来的就是复制链表。
代码如下:
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if( pHead == NULL )
return NULL;
RandomListNode* p = pHead;
while( p ) //复制每个节点
{
RandomListNode* temp = new RandomListNode(p->label);
temp->next = p->next;
p->next = temp;
p = temp->next;
}
p = pHead;
while( p ) //设置random指针
{
if( p->random )
p->next->random = p->random->next;
p = p->next->next;
}
p = pHead;
RandomListNode* res = pHead->next;
while( p ) //拆分
{
RandomListNode* n = p->next;
p->next = n->next;
if( n->next )
n->next = n->next->next;
p = p->next;
}
return res;
}
};
版权声明:本文为qq_36132127原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。