[路飞]leetcode-138.复制带随机指针的链表

前言

这道题应该算是链表访问之后更加升级的一道题目,非常考察我们对链表的理解以及代码的把控,复杂程度不高,但是很好的训练了我们的代码熟练度。

题目描述

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

示例:

image.png

题目分析

这道题麻烦在,我们复制链表之后,还需要处理对应的random节点,如果直接复制链表,那很简单,如下即可

image.png

但是实际上我们还要处理random为对应的复制节点

我们题目处理分为以下三步:

1、一对一复制链表节点到新的链表 2、对应处理一对一节点的复制节点的random指针域 3、拆分链表为两个链表,并且对应返回复制节点的链表

即可完成题目。

所以代码应该怎么写呢?

代码实操演练

  1. 一对一复制链表节点

let p = head;
let q;
// 将每个节点单独复制一份
while (p) {
    q = new Node(p.val);
    q.random = p.random;
    q.next = p.next;
    p.next = q;
    p = q.next;
}

复制代码

此处做了如下操作:

image.png

  1. 处理对应random的值

p = head.next;
while (p) {
    if (p.random) p.random = p.random.next;
    (p = p.next) && (p = p.next);
}
复制代码

此处处理如下:

image.png

image.png

3.最终拆分为两个链表,并返回新的链表


let new_head = head.next;
p = head;
while (p) {
    q = p.next;
    p.next = q.next;
    if (p.next) q.next = p.next.next;
    p = p.next;
}

return new_head;

复制代码

完整效果:

链表.gif

完整代码指路-->

猜你喜欢

转载自juejin.im/post/7041590299394572301
今日推荐