剑指 Offer 35. 复杂链表的复制
请实现 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。
解法一:
1. 复制每一个结点,使得复制后的结点都在当前结点的下一个结点,例如A->B-C变成A->A'->B->B'->C->C'
2. 设置每个副本结点的random指针
3.将链表断开,例如A->A'->B->B'->C->C'变成A'->B'->C',且注意这一步应当将原链表复原
1 /* 2 // Definition for a Node. 3 class Node { 4 int val; 5 Node next; 6 Node random; 7 8 public Node(int val) { 9 this.val = val; 10 this.next = null; 11 this.random = null; 12 } 13 } 14 */ 15 class Solution { 16 public Node copyRandomList(Node head) { 17 if(head == null) 18 return null; 19 20 // 复制每一个结点,使得复制后的结点都在当前结点的下一个结点,例如A->B-C变成A->A'->B->B'->C->C' 21 Node cur = head; 22 Node tmp = null; 23 while(cur != null){ 24 tmp = new Node(cur.val); 25 tmp.next = cur.next; 26 cur.next = tmp; 27 cur = tmp.next; 28 } 29 30 // 第二步将random指针连接起来 31 cur = head; // cur指针复位,重新指向链表头部 32 while(cur != null){ 33 if(cur.random != null){ 34 cur.next.random = cur.random.next; 35 } 36 cur = cur.next.next; 37 } 38 39 // 第三步将链表断开,例如A->A'->B->B'->C->C'变成A'->B'->C',且注意这一步应当将原链表复原 40 Node copyList = head.next, copycur = head.next; 41 42 cur = head; 43 while(cur != null){ 44 cur.next = cur.next.next; 45 cur = cur.next; 46 if(copycur.next != null){ 47 copycur.next = copycur.next.next; 48 copycur = copycur.next; 49 } 50 } 51 return copyList; 52 } 53 }
leetcode运行时间为0ms, 空间为38.7MB
复杂度分析:
时间复杂度:遍历了三次链表,所以时间复杂度为O(3n)
空间复杂度:每个结点都被拷贝了一次,所以空间复杂度为O(n)