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);
    }
}
相关推荐
许小燚3 小时前
线性表——双向链表
数据结构·链表
晚云与城5 小时前
【数据结构】顺序表和链表
数据结构·链表
FirstFrost --sy6 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
liulilittle8 小时前
LinkedList 链表数据结构实现 (OPENPPP2)
开发语言·数据结构·c++·链表
qq_513970449 小时前
力扣 hot100 Day37
算法·leetcode
不見星空9 小时前
leetcode 每日一题 1865. 找出和为指定值的下标对
算法·leetcode
chao_78913 小时前
回溯题解——子集【LeetCode】二进制枚举法
开发语言·数据结构·python·算法·leetcode
GEEK零零七13 小时前
Leetcode 1070. 产品销售分析 III
sql·算法·leetcode
凌肖战13 小时前
力扣网编程274题:H指数之普通解法(中等)
算法·leetcode
Y1nhl16 小时前
力扣_链表_python版本
开发语言·python·算法·leetcode·链表·职场和发展