24 复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路:1)空间复杂度O(1),时间复杂度O(N).
1、复制每个节点,如:复制节点A得到A1,将A1插入节点A后面
2、遍历链表,A1->random = A->random->next;
3、将链表拆分成原链表和复制后的链表
2)空间复杂度O(N),时间复杂度O(N).就是使用一个hashmap存储旧节点和对应的新节点,便于后面找随机节点。
方法1:一定要注意第二步中cur = node -> next,要画个图就清晰了1 -> 1' -> nullptr。第三步中一定一定一定要注意1 -> 1' -> nullptr,最后两个节点的1情况,因为cur = cur -> nex后cur等于nullptr,后面还需要cur -> next,相当于cur -> next -> next,所以必须要检查cur != nullptr,
还有就是if(cur == nullptr),开始自己写成if(cur),这样cur等于空的时候是不执行后面的{}.nullptr相当于0.
/* 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 == nullptr){ return nullptr; } //创建next链表 RandomListNode* cur = pHead; while(cur != nullptr){ RandomListNode* newNode = new RandomListNode(cur -> label); newNode -> next = cur -> next; cur -> next = newNode; cur = newNode -> next; } //copy随机节点 cur = pHead; while(cur != nullptr){ RandomListNode* node = cur -> next; if(cur -> random != nullptr){ node -> random = cur -> random -> next; } cur = node -> next;//这里写错,记住是克隆节点的下一个节点 } //断开 cur = pHead; RandomListNode* newHead = cur -> next; RandomListNode* tmp = newHead; while(cur != nullptr){ cur -> next = newHead -> next; cur = cur -> next; if(cur == nullptr){//1 -> 1' -> nullptr newHead -> next = nullptr; newHead = newHead -> next; break; } newHead -> next = cur -> next;//这里相当于原来的cur -> next -> next newHead = newHead -> next; } return tmp; } };
方法2:
/* 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 == nullptr){ return nullptr; } RandomListNode dummyNode(0); RandomListNode *newHead = &dummyNode; RandomListNode* tmpHead = pHead; unordered_map<RandomListNode*,RandomListNode*> old2new; while(tmpHead != nullptr){ RandomListNode* newNode = new RandomListNode(tmpHead -> label); newHead->next = newNode; old2new[tmpHead] = newNode; newHead = newHead-> next; tmpHead = tmpHead -> next; } //copy 随机节点指针 tmpHead = pHead; while(tmpHead != nullptr){ old2new[tmpHead] -> random = old2new[tmpHead -> random]; tmpHead = tmpHead -> next; } return dummyNode.next; } };