【题目】一种特殊的链表节点描述如下:
class Node{
int value;
Node *next;
Node *rand;
public:
Node(int data,Node *ptr,Node *rand_){
value=data;
}
};
Node类中的value是节点值,next指针和正常单链表中next指针的意义都一样,都指向下一个节点,rand指针是Node类中新增的指针,这个指针可能指向链表中的任意一个节点,也可能指向null。给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数,完成这个链表中所有结构的复制,并返回复制的新链表的头节点。进阶:不使用额外的数据结构,只用有限几个变量,且在时间复杂度为O(N),完成原问题要实现的函数。
这个题用HashMap,用O(N)的额外空间就很好实现,考场建议写这个,直接看代码吧
#include<hash_map>
using namespace std;
using namespace __gnu_cxx;
class copyListWithRand{
public:
class Node{
public:
int value;
Node *next;
Node *rand;
Node(int data,Node *ptr,Node *rand_){
value=data;
next=ptr;
rand=rand_;
}
};
public:
Node copyListWithRand1(Node head){
hash_map <Node, Node> myMap;
Node cur=head;
while(cur.next!= nullptr){
myMap.insert(cur,Node(cur.value,cur.next,cur.rand));
cur=*cur.next;
}
while(cur.next!= nullptr){
myMap[cur].next=myMap[*cur.next].next;
myMap[cur].rand=myMap[*cur.rand].rand;
}
return myMap[head];
}
};
那额外空间O(1)怎么实现这个东西呢?
需要复制的链表如下图:
我们要做的是,复制1节点为_1,然后让1.next指向_1,_1.next指向2…
接下来就是_1,_2, _3,…的rand指向哪里的问题,
假设1的rand指向3,
而三的next指向_3,所以_1的rand就应该是1.rand.next…
我们用这样的结构就省去了map的内存
接下来只要解决新旧链表next之间的关系,问题就解决了。