LeetCode 138 Copy List with Random Pointer 复制带随即指针的链表 Java

**题目:**深度拷贝一个带随即指针的链表,要求新链表内的所有指针不应指向旧链表的节点。

示例1:

复制代码
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例2:

复制代码
输入: head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

**解题思路:**此处主要解决的是如何让新链表中的所有指针指向新复制的节点。此处有两种解法。

解法一:

1)遍历原始链表,并复制所有结点,将新复制的结点插入原节点后方;例如原链表为 A->B->C,复制的节点分别为A',B',C',经过第一步后,原始链表将变为A->A'->B->B'->C->C'

2)再次遍历链表,处理random节点值。我们已知 复制节点与原节点关系为 X'=X.next,所以同理,X'.random=X.random.next, 注意:此处的前提条件是X.random 不能为null。

3)再次遍历链表,拆分原始链表和新链表,再返回新链表即可。

代码:

java 复制代码
/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }


        //遍历原始链表,并复制新节点X',将X'接入X节点后方
        Node currect = head;
        while (currect != null) {
            Node copyNod = new Node(currect.val);
            copyNod.next = currect.next;
            currect.next = copyNod;
            currect = copyNod.next;
        }

        //再次遍历链表,处理random值,关系式为 X'.random=X.random.next
        currect = head;
        while (currect != null) {
            if (currect.random != null) {
                currect.next.random = currect.random.next;
            }
            currect = currect.next.next;
        }

        //第三遍遍历链表,将链表拆分,奇数项节点为原始节点,偶数项系项节点为复制节点。
        Node newHead = head.next;
        Node newCur = newHead;
        currect = head;
        while (currect != null) {

            currect.next = newCur.next;
            currect = currect.next;

            if (currect != null) {
                newCur.next = currect.next;
                newCur = newCur.next;
            }
        }
        return newHead;
    }
}

解题思路二:使用hashmap

1)遍历链表,复制每一个节点并放入hashmap中

2)在hashmap中,遍历原始链表中的每一个节点的值,并对其的next和random值进行赋值

java 复制代码
/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }

        HashMap<Node, Node> map = new HashMap<>();

        //遍历原始链表,复制每一个节点,并将节点放入hashmap中
        Node currect = head;
        while (currect != null) {
            map.put(currect, new Node(currect.val));
            currect = currect.next;
        }

        //再次遍历链表,处理next和random指针
        currect = head;
        while (currect != null) {
            map.get(currect).next = map.get(currect.next);
            map.get(currect).random = map.get(currect.random);
            currect = currect.next;
        }

        return map.get(head);
    }
}
相关推荐
想成为配环境大佬40 分钟前
LeetCode 打家劫舍+删除并获得点数
算法·leetcode·动态规划
Chandler241 小时前
LeetCode:DFS综合练习
算法·leetcode·深度优先
茶不思l1 小时前
数据结构-链表
数据结构·链表
2301_789380491 小时前
力扣每日一题781题解-算法:贪心,数学公式 - 数据结构:哈希
算法·leetcode·职场和发展
小美爱刷题1 小时前
力扣DAY60-61 | 热100 | 回溯:单词搜索、分割回文串
算法·leetcode·职场和发展
爱喝一杯白开水5 小时前
java基础从入门到上手(九):Java - List、Set、Map
java·list·set·map
许_安5 小时前
leetcode刷题日记——单词规律
算法·leetcode·c#
祁同伟.7 小时前
【数据结构 · 初阶】- 带环链表
数据结构·链表
无敌的牛7 小时前
list容器介绍及模拟实现和与vector比较
开发语言·数据结构·list
思麟呀8 小时前
list的模拟实现和反向迭代器的底层
c语言·数据结构·c++·list