题目描述
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的 深拷贝。
方法一
思路分析
- 复制节点跟在原节点后边
- 先复制链表,在复制随机指针,然后分割链表
代码实现
func copyRandomList(head *Node) *Node {
if head == nil {
return head
}
// 复制链表
cur := head
for cur != nil {
clone := &Node{Val: cur.Val, Next: cur.Next}
cur.Next = clone
cur = cur.Next.Next
}
// 复制random
cur = head
for cur != nil {
if cur.Random != nil {
cur.Next.Random = cur.Random.Next
}
cur = cur.Next.Next
}
// 分离链表
cur = head
cloneList := cur.Next
for cur != nil && cur.Next != nil {
temp := cur.Next
cur.Next = cur.Next.Next
cur = temp
}
return cloneList
}
方法二
思路分析
- 将所有节点存到map(有则取之,无则创建)
- 遍历链表依次给新头节点赋值即可
代码实现
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
nodeMap := make(map[*Node]*Node)
newHead := getCopyNode(nodeMap, head)
cur := head
newCur := newHead
for cur != nil {
newNext := getCopyNode(nodeMap, cur.Next)
newRandom := getCopyNode(nodeMap, cur.Random)
newCur.Next = newNext
newCur.Random = newRandom
newCur = newCur.Next
cur = cur.Next
}
return newHead
}
func getCopyNode(nodeMap map[*Node]*Node, node *Node) *Node {
if value, ok := nodeMap[node]; ok {
return value
} else {
if node == nil {
return nil
}
copyNode := &Node{Val: node.Val}
nodeMap[node] = copyNode
return copyNode
}
}