(Java)链表OJ题---LeetCode 138 复制带随机指针的链表

简介: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

一. 题目描述

题目链接:复制带随机指针的链表


题目:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。


返回复制链表的头节点。


示例:

image.png


自己举一个例子:

image.png



二. 方法一解析及参考代码

我们采用链表相关概念来做,具体的做法分为三大步骤:


1. 复制链表节点进行链接,复制链接完后长这样:


image.png


2. 给复制的新节点赋随机指针域,赋完长这样:

image.png


3. 将复制的新链表从原链表中断开,断开为这样:

image.png



参考代码:

class Solution {
    public Node copyRandomList(Node head) {
        //判空操作,如果链表为空直接返回
        if(head == null){
            return head;
        }
        //复制链接
        Node cur = head;
        while(cur != null){
            Node newNode = new Node(cur.val);//以原链表的值new新节点
            newNode.next = cur.next;
            cur.next = newNode;
            cur = newNode.next;
        }
        //给复制的节点赋随机值
        cur = head;
        Node newNode = cur.next;
        while(cur != null){
            if(cur.random != null){
                newNode.random = cur.random.next;
            }
            cur = newNode.next;
            if(cur != null){
                newNode = cur.next;
            }
        }
        //将复制的链表从原链表当中断开
        cur = head;
        Node newHead = cur.next;//新链表头节点
        Node newCur = newHead;//新链表节点的引用
        while(cur != null){
            cur.next = newCur.next;
            cur = newCur.next;
            if(cur != null){
                newCur.next = cur.next;
                newCur = cur.next;
            }
        }
        return newHead;
    }
}


三. 方法二解析及参考代码

我们借助hashmap这一数据结构来做,具体做法分为三大步骤:


1. 遍历原链表,将原链表的节点作为K,新复制的节点作为V,将K与对应的V存入hashmap中,存入之后为这样:

image.png



2. 将hashmap中V的节点依次链接起来,链接后为这样:

image.png



3. 给hashmap中V的节点依次赋随机指针域,完成后为这样:

image.png


参考代码:

class Solution {
    public Node copyRandomList(Node head) {
        Map<Node,Node> m = new HashMap<>();
        Node cur = head;
        //hashmap中存放的K-V为:原链表的节点-新复制的节点
        while(cur != null){
            m.put(cur,new Node(cur.val));
            cur = cur.next;
        }
        cur = head;
        while(cur != null){
            m.get(cur).next = m.get(cur.next);//将V中的节点链接起来
            m.get(cur).random = m.get(cur.random);//给V中的节点赋随机指针域
            cur = cur.next;
        }
        return m.get(head);
    }
}


相关文章
|
3月前
|
Java
java数据结构,双向链表的实现
文章介绍了双向链表的实现,包括数据结构定义、插入和删除操作的代码实现,以及双向链表的其他操作方法,并提供了完整的Java代码实现。
java数据结构,双向链表的实现
|
2月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
27 3
|
4月前
|
存储 Java
|
4月前
|
存储 Java
java实现单链表的创建、增、删、改、查
这篇文章详细介绍了Java中如何实现单链表的创建以及对单链表进行增加、删除、修改、查询等操作的方法,并提供了相应的代码示例。
java实现单链表的创建、增、删、改、查
|
4月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
24 1
|
4月前
|
存储 Java
【Java集合类面试十】、HashMap中的循环链表是如何产生的?
在多线程环境下,HashMap在扩容时如果发生条件竞争,元素的插入顺序可能形成循环链表,导致死循环。
|
4月前
|
存储 Java
java实现双向链表的增删改查
这篇文章展示了如何在Java中实现双向链表的增加、删除、修改和查询操作,并通过代码示例演示了在双向链表中存储和操作学生信息的过程。
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
56 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
48 0
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解