一、题目描述
请实现 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 。
二、思路讲解
创建一个哈希表,将旧指针与新建的指针的映射逐一放入哈希表中,然后再创建新节点直接的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) { Map<Node, Node> map = new HashMap<>(); Node p = head; //将旧节点与新创建的节点一一对应,放入map中 while(p != null){ map.put(p, new Node(p.val)); p = p.next; } p = head; //构建新链表的next和random指向 while(p != null){ map.get(p).next = map.get(p.next); map.get(p).random = map.get(p.random); p = p.next; } //返回新链表的头指针 return map.get(head); } }
四、时空复杂度分析
时间复杂度: O(N)
空间复杂度: O(N)
五、代码优化
使用hashmap的代码思路比较清晰,但map会占用O(N)的空间复杂度。我们可以在原链表上进行修改,将时间复杂度降为常数阶。
例如我们可以构建 原节点1 -> 新节点1 -> 原节点2 -> 新节点2 -> ……的结构,这样很容易就能得到新节点的random指向,即新节点.random = 原节点. random.next。
然后再将新旧链表拆分出来就可以了。
/* // 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; Node cur = head; // 1. 复制各节点,并构建拼接链表 while(cur != null) { Node tmp = new Node(cur.val); tmp.next = cur.next; cur.next = tmp; cur = tmp.next; } // 2. 构建各新节点的 random 指向 cur = head; while(cur != null) { if(cur.random != null) cur.next.random = cur.random.next; cur = cur.next.next; } // 3. 拆分两链表 cur = head.next; Node pre = head, res = head.next; while(cur.next != null) { pre.next = pre.next.next; cur.next = cur.next.next; pre = pre.next; cur = cur.next; } pre.next = null; // 单独处理原链表尾节点 return res; // 返回新链表头节点 } }
时间复杂度: O(N)
空间复杂度: O(1)