职务地址:
题意:对一个有回路的链表的深复制
解题:这道题我AC了之后才发现理解错了题意,然后就參考了以下这篇文章。
假设想看这道题的解题思路的话,请移步
拓展:假如题目给的节点不是链表的头节点。而是链表中的随意一个节点,在保证从给的点能遍历所有节点的情况下,深复制这个链表。
那么该怎么做呢?
思路:事实上一想,和原题的区别仅仅有节点是否是头节点而已,那么我们就从给的这个节点找到原节点即可了。
遍历的过程用dfs,再用map来推断一个节点是否被遍历过。如今唯一的难点就是怎样找到头节点,这里用并查集就OK了。
路径压缩后并查集的复杂度接近O(1),因为map的复杂度接近O(logN),这样dfs的复杂度大概是O(NlogN)。
技巧:dfs到一个新的节点时,用map将其映射成一个唯一的整数cnt,并在这时初始化并查集fa[cnt]。
//#include "stdafx.h"#include#include #include
faCnt:cnt); RandomListNode *next = ptr->next; RandomListNode *random = ptr->random; it=mp.find(next); if(it==mp.end()){ dfs(next,faCnt>0?faCnt:cnt); } else{ fa[mp[next]] = fa[cnt]; } it=mp.find(random); if(it==mp.end()){ dfs(random,0);//0表示不能确定其父节点 } } //非拓展部分解法 RandomListNode* deepCopy(RandomListNode *head){ //在原链表上双倍复制链表 RandomListNode *ptr1 = head, *ptr2 = NULL; while(ptr1 != NULL){ ptr2 = new RandomListNode(ptr1->label); ptr2->next = ptr1->next; ptr1->next = ptr2; ptr1=ptr2->next; } //复制原链表的random关系 ptr1 = head, ptr2 = NULL; while(ptr1 != NULL){ ptr2 = ptr1->next; if(ptr1->random) ptr2->random = ptr1->random->next; ptr1=ptr2->next; } //将原列表分裂成两个列表 RandomListNode *H =NULL, *ptr3; ptr1 = head, ptr2 = NULL; while(ptr1 != NULL){ ptr2 = ptr1->next; if(H==NULL){ H = ptr2; ptr3 = H; } else{ ptr3->next = ptr2; ptr3 = ptr2; } ptr1->next = ptr2->next; ptr1 = ptr1->next; } return H; } };
版权声明:本文博客原创文章,博客,未经同意,不得转载。