给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
示例:
输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。
解法1:
/** * 创建一个存放节点的复制节点的map */ static Map<Node, Node> visitedMap = new HashMap<>(8); public static Node copyRandomList(Node head) { /*当头节点为null时返回null*/ if (head == null) { return null; } /*先看复制节点存不存在,如果存在直接返回*/ Node value = visitedMap.get(head); if (value != null) { return value; } /*创建一个复制节点*/ Node node = new Node(head.val, null, null); /*将复制节点放入map中*/ visitedMap.put(head, node); /*复制节点的下一个节点就是head的下个节点*/ node.next = copyRandomList(head.next); /*复制节点的随机节点就是head的随机节点*/ node.random = copyRandomList(head.random); return node; }
解法2:
public static Node copyRandomList1(Node head) { /*当头节点为null时返回null*/ if (head == null) { return null; } /*定义一个头节点的引用*/ Node pre = head; /*循环里操作是把copy节点放在当前节点后面*/ while (pre != null) { /*copy当前节点*/ Node copy = new Node(pre.val, null, null); /*copy的节点的下一个节点是当前节点的下一个*/ copy.next = pre.next; /*当前节点的下一个是copy节点*/ pre.next = copy; /*由于当前节点的下一个节点是自己copy节点,所以当前节点要找自己的下下一个继续循环*/ pre = pre.next.next; } /*头节点引用再次指向头节点*/ pre = head; /*这步循环操作是把当前节点后面的copy节点的random赋值为与当前节点同步的copy节点*/ while (pre != null) { pre.next.random = pre.random != null ? pre.random.next : null; pre = pre.next.next; } /*头节点引用再次指向头节点*/ pre = head; /*定义一个copy头节点引用*/ Node h = pre.next; /*这步循环操作是把当前节点后面的copy节点的next赋值为与当前节点同步的copy节点,并与copy节点分离成2个不同的链*/ while (pre != null) { Node c = pre.next; if (c != null) { Node b = pre.next.next; pre.next = b; if (b != null) { c.next = b.next; } pre = b; } } return h; }
原文地址:https://www.cnblogs.com/wuyouwei/p/11795809.html
时间: 2024-11-10 01:57:55