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);
    }
}
相关推荐
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
To_OC3 天前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
To_OC3 天前
LC 200 岛屿数量:经典 DFS 入门题,我第一次写居然连方向都搞错了
javascript·算法·leetcode
To_OC4 天前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
To_OC6 天前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
To_OC7 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
想吃火锅100513 天前
【leetcode】121.买卖股票的最佳时机js/c++
算法·leetcode·职场和发展
凌波粒13 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
疯狂成瘾者13 天前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表