剑指 Offer 35. 复杂链表的复制
题目链接:
剑指 Offer 35. 复杂链表的复制 - 力扣(LeetCode) (leetcode-cn.com)
1.法一:使用HashMap,利用其映射关系来进行实现(多占一个哈希表的空间)
1 public Node copyRandomList1(Node head) { 2 HashMap<Node,Node> map = new HashMap<>();//建立原链表节点和新复制的链表节点的映射关系 3 Node cur = head; 4 while (cur != null) { 5 map.put(cur, new Node(cur.val));//为新的链表节点开辟好空间 6 cur = cur.next; 7 } 8 cur = head; 9 while (cur != null) { 10 map.get(cur).next = map.get(cur.next);//将新链表节点的next指针进行连接 11 map.get(cur).random = map.get(cur.random);//将新链表节点的rand指针进行连接 12 cur = cur.next; 13 } 14 return map.get(head); 15 }
2.法二:使用相邻节点拷贝后分离的方法来进行实现(多注意考虑空指针问题)
此处养成一个良好的链表编码习惯:如果链表的下一个节点要改变,则养成用一个next存改变前的节点的next值的习惯
1 public Node copyRandomList2(Node head) { 2 if (head == null) {//空表情况要额外考虑 3 return null; 4 } 5 Node p = head; 6 //如果链表的下一个节点要改变,则养成用一个next存改变前的节点的next值的习惯 7 Node next = null; 8 while (p != null) {//相邻节点拷贝一个复制节点 9 next = p.next; 10 p.next = new Node(p.val); 11 p.next.next = next; 12 p = next;//不要忘记链表要一直向下走 13 } 14 p = head; 15 Node q = null; 16 while (p != null) {//调整拷贝链表的随机节点指向 17 next = p.next.next; 18 q = p.next; 19 q.random = p.random != null ? p.random.next : null; 20 p = next; 21 } 22 //把两个链表进行分离 23 Node newHead = head.next;//把这个拷贝链表的头进行保存 24 p = head; 25 while (p != null) { 26 next = p.next.next; 27 q = p.next; 28 p.next = next; 29 q.next = next != null ? next.next : null; 30 p = next; 31 } 32 return newHead; 33 }