复杂链表的复制
请实现 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]]
题解
-
暴力法
- 算法思想
- 直接复制,然后从头开始,寻找 random 指针
- 复杂度分析
- 时间复杂度 O(n^2):寻找每一个 random 指针需要遍历一遍链表,所以是 n^2
- 空间复杂度 O(n)
- 算法思想
-
哈希表法
- 算法思想
- 直接复制 node
- 将 《node,node‘ 》 存放到 hashmap 中
- 复杂度分析
- 时间复杂度O(n)
- 空间复杂度 O(n)
- 算法思想
-
利用原始链表存储信息法
- 算法思想
- 复制链表中的节点,并将复制的节点连接到被复制的节点之后
- 使被复制的节点的 random 指针指向 node.random 指针之后
- 分离两个链表
- 复杂度分析
- 时间复杂度O(n)
- 空间复杂度 O(1)
/* // 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 headNode = head; copyNoded(headNode); linkRandom(headNode); return splitLinkList(headNode); } void copyNoded(Node node){ while(node != null){ Node copyNode = new Node(node.val); copyNode.next = node.next; node.next = copyNode; node = copyNode.next; } } void linkRandom(Node node){ while(node != null){ if(node.random != null){ node.next.random = node.random.next; } node = node.next.next; } } Node splitLinkList(Node node){ Node copyNodeHead = null,copyNode = null; if(node != null){ copyNodeHead = copyNode = node.next; node.next = copyNode.next; node = node.next; } while(node != null){ copyNode.next = node.next; copyNode = copyNode.next; node.next = copyNode.next; node = node.next; } return copyNodeHead; } }
- 算法思想
总结
-
这道题花了我几个小时的时间,链表的 split 总是写错,而且不知道怎么 debug,总是持着惯性思维,导致脑子 debug 不出结果。
-
此次问题主要出现在链表的 split 没有将链表的下一个节点转移至下下个节点上。哈哈哈哈,你好菜呀!!不过还是要加油
-
还有。当节点需要 next 的次数过多,可以使用哨兵节点,比如在某一时刻,原始 node 在复制的 node 之前,这样就可以避免 nullpointException
干他呀的!
-