138. 随机链表的复制 --力扣 --JAVA

题目

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

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

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

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0n-1);如果不指向任何节点,则为 null

你的代码 接受原链表的头节点 head 作为传入参数。

解题思路

  1. 先排除特殊情况:若链表为null则直接返回null;
  2. 使用Map存储原始链表的节点和对应索引;
  3. 使用List来存储复制后链表的节点;
  4. while循环完成节点复制、next链接和存储;
  5. 从Map和List中获取首节点进行第二次遍历;
  6. 第二次遍历建立random链接。

代码展示

java 复制代码
class Solution {
    public Node copyRandomList(Node head) {
        //排除特殊情况
        if (head == null){
            return null;
        }
        Node ans = new Node(head.val);
        //需要获取random的索引,所以用map比遍历List要便捷
        Map<Node, Integer> headMap = new HashMap<>();
        //只需要根据索引获取对应节点,List本身是有序的,所以不需要用Map
        List<Node> ansList = new ArrayList<>();
        int index = 0;
        headMap.put(head, index);
        ansList.add(ans);
        //遍历生成所有节点并存储起来
        while (head.next != null){
            head = head.next;
            ans.next = new Node(head.val);
            index++;
            headMap.put(head, index);
            ansList.add(ans.next);
            ans = ans.next;
        }
        for (Node node : headMap.keySet()){
            if(headMap.get(node) == 0){
                head = node;
                break;
            }
        }
        ans = ansList.get(0);
        while (head != null && ans != null){
            Integer num = headMap.get(head.random);
            Node temp = null;
            if(num != null){
                temp = ansList.get(num);
            }
            ans.random = temp;
            head = head.next;
            ans = ans.next;
        }
        return ansList.get(0);
    }
}
相关推荐
ideaout技术团队2 小时前
leetcode学习笔记2:多数元素(摩尔投票算法)
学习·算法·leetcode
代码充电宝2 小时前
LeetCode 算法题【简单】283. 移动零
java·算法·leetcode·职场和发展
不枯石5 小时前
Matlab通过GUI实现点云的均值滤波(附最简版)
开发语言·图像处理·算法·计算机视觉·matlab·均值算法
不枯石5 小时前
Matlab通过GUI实现点云的双边(Bilateral)滤波(附最简版)
开发语言·图像处理·算法·计算机视觉·matlab
白水先森7 小时前
C语言作用域与数组详解
java·数据结构·算法
想唱rap7 小时前
直接选择排序、堆排序、冒泡排序
c语言·数据结构·笔记·算法·新浪微博
老葱头蒸鸡8 小时前
(27)APS.NET Core8.0 堆栈原理通俗理解
算法
视睿8 小时前
【C++练习】06.输出100以内的所有素数
开发语言·c++·算法·机器人·无人机
柠檬07119 小时前
matlab cell 数据转换及记录
算法
YuTaoShao10 小时前
【LeetCode 每日一题】2221. 数组的三角和
数据结构·算法·leetcode