题意:

image.png

解题思路:

  1. 思路:O(n)
  2. 第一步,将新生成的结点放在原结点的后边,即 1 -> 1' -> 2 -> 2' -> NULL。新结点的随机指针指向原结点。
  3. 第二步,扫描合成的链表,更新新结点的随机指针为原来指向结点的 next//$p->next->random = $p->random->next;
  4. 第三步,将两个链表分离,恢复原链表,返回新链表的头结点。

PHP代码实现:

  1. /**
  2. * Definition for a Node.
  3. * class Node {
  4. * public $val = null;
  5. * public $next = null;
  6. * public $random = null;
  7. * function __construct($val = 0) {
  8. * $this->val = $val;
  9. * $this->next = null;
  10. * $this->random = null;
  11. * }
  12. * }
  13. */
  14. class Solution {
  15. /**
  16. * @param Node $head
  17. * @return Node
  18. */
  19. function copyRandomList($head) {
  20. //复制一个小弟
  21. for ($p = $head; $p; $p = $p->next->next) {
  22. $q = new Node($p->val);
  23. $q->next = $p->next;
  24. $p->next = $q;
  25. }
  26. //复制random指针
  27. for ($p = $head; $p; $p = $p->next->next) {
  28. if ($p->random) {
  29. $p->next->random = $p->random->next;
  30. }
  31. }
  32. //拆分两个链表
  33. $dummy = new Node(-1);
  34. $cur = $dummy;
  35. for ($p = $head; $p; $p = $p->next) {
  36. $q = $p->next;
  37. $cur = $cur->next = $q;
  38. $p->next = $q->next;
  39. }
  40. return $dummy->next;
  41. }
  42. }

GO代码实现:

  1. /**
  2. * Definition for a Node.
  3. * type Node struct {
  4. * Val int
  5. * Next *Node
  6. * Random *Node
  7. * }
  8. */
  9. func copyRandomList(head *Node) *Node {
  10. if head == nil {
  11. return head
  12. }
  13. // 复制节点,紧挨到到后面
  14. // 1->2->3 ==> 1->1'->2->2'->3->3'
  15. cur := head
  16. for cur != nil {
  17. clone := &Node{Val: cur.Val, Next: cur.Next}
  18. temp := cur.Next
  19. cur.Next = clone
  20. cur = temp
  21. }
  22. // 处理random指针
  23. cur = head
  24. for cur != nil {
  25. if cur.Random != nil {
  26. cur.Next.Random = cur.Random.Next
  27. }
  28. cur = cur.Next.Next
  29. }
  30. // 分离两个链表
  31. cur = head
  32. cloneHead := cur.Next
  33. for cur != nil && cur.Next != nil {
  34. temp := cur.Next
  35. cur.Next = cur.Next.Next
  36. cur = temp
  37. }
  38. // 原始链表头:head 1->2->3
  39. // 克隆的链表头:cloneHead 1'->2'->3'
  40. return cloneHead
  41. }