📑 题目:138. 复制带随机指针的链表

🚀 本题 LeetCode 传送门

题目大意

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。

解题思路

  • 这道题严格意义上是数据结构题,根据给定的数据结构,对它进行深拷贝。

  • 先将每个节点都复制一份,放在它的 next 节点中。如此穿插的复制一份链表。

    138. 复制带随机指针的链表 - 图1

    再将穿插版的链表的 random 指针指向正确的位置。

    138. 复制带随机指针的链表 - 图2

    再将穿插版的链表的 next 指针指向正确的位置。最后分开这交织在一起的两个链表的头节点,即可分开 2 个链表。

    138. 复制带随机指针的链表 - 图3

代码

  1. package leetcode
  2. // Node define
  3. type Node struct {
  4. Val int
  5. Next *Node
  6. Random *Node
  7. }
  8. func copyRandomList(head *Node) *Node {
  9. if head == nil {
  10. return nil
  11. }
  12. tempHead := copyNodeToLinkedList(head)
  13. return splitLinkedList(tempHead)
  14. }
  15. func splitLinkedList(head *Node) *Node {
  16. cur := head
  17. head = head.Next
  18. for cur != nil && cur.Next != nil {
  19. cur.Next, cur = cur.Next.Next, cur.Next
  20. }
  21. return head
  22. }
  23. func copyNodeToLinkedList(head *Node) *Node {
  24. cur := head
  25. for cur != nil {
  26. node := &Node{
  27. Val: cur.Val,
  28. Next: cur.Next,
  29. }
  30. cur.Next, cur = node, cur.Next
  31. }
  32. cur = head
  33. for cur != nil {
  34. if cur.Random != nil {
  35. cur.Next.Random = cur.Random.Next
  36. }
  37. cur = cur.Next.Next
  38. }
  39. return head
  40. }

**