曾格的github

剑指offer-复杂链表的复制

描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。

 

 

求解思路:

  1. 第一个循环先构建非随机链(即只考虑next指针),并用map记录label与新链表各节点的映射
  2. 第二个循环根据map,完善随机指针。

代码:

 

 1 /*
 2 struct RandomListNode {
 3     int label;
 4     struct RandomListNode *next, *random;
 5     RandomListNode(int x) :
 6             label(x), next(NULL), random(NULL) {
 7     }
 8 };
 9 */
10 class Solution {
11 public:
12     RandomListNode* Clone(RandomListNode* pHead) {
13         //  如果把复杂链表看作随机链和非随机链,那先确定非随机链
14         // 然后依次检验每个节点的随机指针,读取val,通过val确定新链的随机指针
15         // 改进:在构建非随机链表时,新建map映射 val和random(这里记录节点)
16         std::map<int,RandomListNode*> lm;
17         RandomListNode* newHead=NULL;
18         RandomListNode* tail;   // 记录尾节点
19         // 完成非随机链表的构建
20         RandomListNode* ergNode=pHead;
21         while(ergNode!=nullptr){
22             RandomListNode* rn=new RandomListNode(ergNode->label);
23             if(newHead==nullptr){
24                 newHead=rn;
25             }else{
26                 tail->next=rn;
27             }
28             tail=rn;
29             // 构建label和node的映射
30             // lm.insert(pair<int,RandomListNode*>(rn->label,rn));
31             lm[rn->label]=rn;
32             ergNode=ergNode->next;
33         }
34         // 再用一个循环完成随机链表的构建
35         ergNode=pHead;  // 遍历原有链表
36         RandomListNode* repNode=newHead;  // 补充现有链表
37         while(ergNode!=nullptr){
38             if(ergNode->random!=nullptr){
39                 repNode->random=lm[ergNode->random->label];
40                 int f=1;
41             }
42             ergNode=ergNode->next;
43             repNode=repNode->next;
44         }
45         return newHead;
46     }
47 };

 

 

 

posted @ 2021-07-28 22:33  曾格  阅读(28)  评论(0编辑  收藏  举报
Live2D