这个题目很早就被我当成“简单题”ac了,其实现在想想,还是自己水平太菜,才只能想到那种需要O(n)空间的方法,然后就自鸣得意了
看过之前有个大牛说过,“很多牛人,他们并不是能做出很难的题或者是想出很难的算法,大部分是把简单的东西,理解的很透彻,很到位”。
唉,实力不行,心态更不能膨胀。
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.
O(n²)暴力的方法肯定是不给力的
于是我想到用map来做,把每个new出来的节点都放到一个vector里,然后把每个label都存到map里面,记录下它的位置,这样当我复制random指针时,就可以通过map来找到节点所在vector中的index,相当于O(1)的时间就可以找到每个random指针所指向的内容了。
class Solution {
public:
map<int,int> label_index;
vector<RandomListNode*> nodes;
RandomListNode *copyRandomList(RandomListNode *head) {
if(head==NULL)
return NULL;
RandomListNode* node = head;
while(node!=NULL){
label_index.insert(pair<int,int>(node->label,label_index.size()));
nodes.push_back(new RandomListNode(node->label));
node = node->next;
}
for(int i=0;i<nodes.size()-1;i++){
nodes[i]->next = nodes[i+1];
}
node = head;
int k = 0;
while(node!=NULL){
RandomListNode* rd = node->random;
if(rd==NULL){
node= node->next;
k++;
continue;
}
int label = node->random->label;
map<int,int>::iterator it = label_index.find(label);
nodes[k]->random = nodes[it->second];
k++;
node = node->next;
}
return nodes[0];
}
};
后来看到了一个很屌的方法 来源:http://zhedahht.blog.163.com/blog/static/254111742010819104710337/
即,把每个new出来的节点,都插入到原来链表中的对应的那个节点之后,如上图。
这样,其实相当于能在O(1)的时间找到自己应该指向的random指针。如图:
然后,再把这个链表拆开即可,即奇数位置的节点属于原来的链表,偶数位置的节点属于copy出来的链表。
屌爆的思路。
/**
* 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:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head==NULL)
return NULL;
head = cross_insert(head);
random_insert(head);
return select(head);
}
RandomListNode* select(RandomListNode* &node){
RandomListNode* head = NULL,*tail=NULL,*head2=NULL,*tail2=NULL;
while(node!=NULL){
if(head==NULL){
head =tail= node;
head2 =tail2=node->next;
node = node->next->next;
head->next=NULL;
head2->next=NULL;
}else{
tail->next = node;
tail2->next = node->next;
node = node->next->next;
tail = tail->next;
tail->next=NULL;
tail2 = tail2->next;
tail2->next=NULL;
}
}
node = head;
return head2;
}
RandomListNode* cross_insert(RandomListNode* head){
RandomListNode* node = head;
while(node!=NULL){
RandomListNode* t = node->next;
node->next = new RandomListNode(node->label);
node->next->next = t;
node = t;
}
return head;
}
void random_insert(RandomListNode* head){
RandomListNode* node = head;
while(node!=NULL){
RandomListNode* ran = node->random;
if(ran!=NULL)
node->next->random = ran->next;
node = node->next->next;
}
}
};
===================================updated on 4th, Sep, 2014=====================================
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head==NULL)
return NULL;
RandomListNode* h=NULL,*t=NULL;
RandomListNode* node = head;
while(node!=NULL){
RandomListNode* tmp = new RandomListNode(node->label);
tmp->next = node->next;
node->next = tmp;
node = tmp->next;
}
node = head;
while(node!=NULL){
if(node->random!=NULL)
node->next->random = node->random->next;
node= node->next->next;
}
node = head;
while(node!=NULL){
if(h==NULL){
h = node->next;
node->next = h->next;
h->next=NULL;
t = h;
}else{
t->next = node->next;
t = t->next;
node->next = t->next;
t->next=NULL;
}
node = node->next;
}
return h;
}
};
回头看以前的代码,写的真心丑
===================================updated on 4th, Sep, 2014=====================================