复制一个复杂链表

132 阅读1分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

题目

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null

示例 1:

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

示例 2:

输入: head = [[1,1],[2,1]]
输出: [[1,1],[2,1]]

示例 3:

输入: head = [[3,null],[3,0],[3,null]]
输出: [[3,null],[3,0],[3,null]]

示例 4:

输入: head = []
输出: []
解释: 给定的链表为空(空指针),因此返回 null。

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

题目分析

这道题目同样考察的是链表的操作,只是这个链表和普通的链表有所不同,普通链表的定义是

public class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
 }

一个val,一个next,那么这个链表的定义比普通链表多了一个属性,就是random,这个是随机指向一个节点,复制操作的时候可以先将原先的链表遍历一遍,使用一个map记录数据,map的key是当前节点,value是当前节点的val值构成的节点,也就是key和value一样,value值的所有节点就是复制的节点,我们需要做的就是将value值存储的节点构建连接到一起,这时候再遍历一遍链表,构建新的链表完成新链表的节点的连接就行了。

代码实现

/*
// 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;
    }
}
*/
//35
class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        Node currentNode = head;
        Map<Node,Node> map = new HashMap<>();
        while (currentNode!=null) {
            map.put(currentNode,new Node(currentNode.val));
            currentNode = currentNode.next;
        }
        currentNode = head;

        while (currentNode!=null) {
            map.get(currentNode).next = map.get(currentNode.next);
            map.get(currentNode).random = map.get(currentNode.random);
            currentNode = currentNode.next;
        }

        return map.get(head);
    }
}

第一段for循环就是复制所有的节点, currentNode = head;表示回到链表的表头

第二段for循环就是将复制的节点按照原先的连接信息进行连接,map.get(head);表示回到复制链表的表头

这是我用java实现的功能,每个题都用不同的解法和写法,我大体整理了一下自己的思路然后就写了,也没有再想其他的方法,如果你有更好的解法,欢迎和我留言,我们一起进步,一起学习数据结构,共同进步,通过这道题能更熟悉链表的操作。