2021-10-16

剑指offer 35题  复制复杂链表

把原题用我们能理解的白花来翻译一下:

复制出一个跟原链表一摸一样的链表,原链表每个节点的值是多少,你复制出来的链表的值就是多少,原链表每个节点的random指向哪,你复制出来的链表的节点的random也要指向对应的位置。

原链表:

 

 

 

说一下思路:3个步骤

步骤1:复制节点

 

我们步骤一要实现出来的就是上图所示。这个步骤可以理解为链表的插入,需要插入的节点我们在循环里面创建

for( auto p = head;  p; )

{

        auto newp = new Node(p->val);//复制出当前节点

        auto temp = p->next;//定义一个指针一直指向p的下一个

        p->next = newp;//这块改变的p的下一个指向,所以前面要预先定义以一个指针指向p->next

        newp->next = temp;

        p = temp;   //这三步就是链表节点的插入

}

 

步骤2:复制random

这块我们暂且定义p=head,p是我们链表的头

上图是我们本步骤的一个思路,为了怕大家不理解代码,我在图中进行了标注。需要注意,我们本步骤2是在步骤1的基础之上进行操作,也就是说此时链表已经完成了复制,此时p->next是我们已经复制出来的一个节点。通过上图我们可以发现1   1‘    2   2’  的一个关系:1----2    1‘-----2’   ,然而2的下一个就是2‘,即2->next = 2’  ,2是1的random,1又是头,所以有p->random->next = 2' ,2'是1‘的random,1’又是头的下一个,所以有2’ = p->next->random。

故p->random->next = p->next->random;

 

for( p = head;  p;  p = p->next->next )

{

        if( p->random )

        {

                p->next->random = p->random->next; 

        }

}

 

步骤3:分离

上图是我们要得到的结果,什么意思呢,就是从1   1‘    2  2’   3  3‘  4  4’  中分离出  1‘  2’   3‘  4’

p = head(也就是1)。p->next是1‘,就是我们要分离出来的

 

auto dummy = new Node(-1);   //建立一个虚拟节点

auto cur = dummy;                      //随便定义一个指针指向该虚拟节点,不定义也没事

for( auto p = head;  p;  p=p->next )

{

        cur->next = p->next;   //虚拟节点的下一个指向头节点的下一个,也就是1’

        cur = cur->next;     //虚拟节点后移

        p->next = p->next->next;    //头指针后移     此时p要一次移动2步,

}

return dummy->next;   //此时我们返回虚拟节点的下一个  1‘即可。

附上力抠代码原图:

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值