请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例
- 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
- 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
- 解释:给定的链表为空(空指针),因此返回 null。
提示
- -10000 <= Node.val <= 10000
- Node.random 为空(null)或指向链表中的节点。
- 节点数目不超过 1000 。
方法一:回溯+哈希表
算法如下:
- 检查当前节点是否拷贝过:
- 如果没有拷贝过,把当前节点存放到存放到哈希表中,并递归创建 “当前节点的后继节点” 和 “当前节点的随机节点”;
- 如果已经拷贝过,直接从哈希表中取出拷贝的节点的指针返回。
代码如下:
复杂度分析
- 时间复杂度:O(n),其中 n 是链表的长度。对于每个节点,我们至多访问其“后继节点”和“随机节点”各一次,均摊每个点至多被访问两次。
- 空间复杂度:O(n),其中 n 是链表的长度。为哈希表的空间开销。
方法二:迭代+节点拆分
算法如下:
- 复制各节点,并构建拼接链表,即:a→b→c 变为 a→a1→b→b1→c→c1;
- 构建各新节点的 random指向,经过步骤一后,当前节点的新节点的随机节点对应的是原随机节点的后续节点,即:a.a1.random = a.random.next;
- 拆分两链表,即:a1.next = = a.next.next = b1。
代码如下:
复杂度分析
- 时间复杂度:O(n),其中 n 是链表的长度。我们只需要遍历该链表三次。
- 空间复杂度:O(1)。注意返回值不计入空间复杂度。
END
世上无难事,只要肯攀登在,赠友人。
好兄弟可以点赞并关注我的公众号“javaAnswer”,全部都是干货。