35.M 复杂链表的复制
题目
https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof
请实现 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 。
解题思路
方法一:使用map保存原节点和新节点的映射关系,然后再重新给新节点赋值next和rand指针。如果某个节点在老链表中指向节点N,那么新节点在新链表中应该指向N'。空间复杂度O(n)
方法二:先复制每个节点,然后把节点N'拼在N的后面,然后重新设置sibling指针,最后再拆分链表。空间复杂度O(1)
实现代码
type Node struct {
Val int
Next *Node
Random *Node
}
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
//复制链表节点,并插入原链表
p := head
for p != nil {
cloned := &Node{Val: p.Val}
cloned.Next = p.Next
p.Next = cloned
p = cloned.Next
}
//给复制出来的节点赋值Rand指针
p = head
for p != nil {
if p.Random != nil {
p.Next.Random = p.Random.Next
}
p = p.Next.Next
}
//拆分链表
newHead := head.Next
p = head
p1 := newHead
for p != nil {
p.Next = p1.Next
if p1.Next != nil {
p1.Next = p1.Next.Next
}
p = p.Next
p1 = p1.Next
}
return newHead
}
Last updated
Was this helpful?