输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
代码
static class ListNode { int val; ListNode next; ListNode other; public ListNode(int val) { this.val = val; } @Override public String toString() { return "ListNode{" + "val=" + val + ", next=" + (next == null ? "null" : next.val) + ", other=" + (other == null ? "null" : other.val) + "}"; } } /** * 复制 * 原链表为a->b->c * 复制后为a->a1->b->b1->c->c1 * @param head */ private static void copy(ListNode head) { ListNode listNode = head; while (listNode != null) { // 根据当前节点的内容创建新的节点 ListNode copy = new ListNode(listNode.val); copy.next = listNode.next; // 将新节点作为当前节点的next节点,而新节点的next指向了当前节点的原next节点 // 原来是a->b,选择则是a->a1->b listNode.next = copy; // 指向下一节点,重复上述操作 listNode = copy.next; } } /** * 设置other节点 * @param head */ private static void setOther(ListNode head) { ListNode listNode = head; // listNode是原链表节点,copy是对应的复制节点,同时移动指针遍历 while (listNode != null) { // 当前节点下一节点为其复制节点 ListNode copy = listNode.next; // 当前节点的other节点不为null时,复制节点的other应为源节点other节点的next节点 // a -> a1 -> b -> b1 a1是a的复制节点,b1是b的复制节点 // | ↑ a.other是b,b.next节点是b1(由第一步复制保证的) // |_ _ _ _ _ | 所以a1的other节点是a.other即b的next,也就是a.other.next if (listNode.other != null) { copy.other = listNode.other.next; } // 当前节点指向其复制节点的下一节点,即源节点的原next节点,重复上述操作 listNode = copy.next; } } /** * 断开与原链表的连接 * @param head * @return */ private static ListNode disConnect(ListNode head) { ListNode listNode = head; ListNode copyHead = null; ListNode copyNode = null; if (listNode != null) { // 复制链表的头节点就是目前链表头节点的next节点(即其复制节点) copyHead = listNode.next; // 用于遍历复制链表 copyNode = listNode.next; // 当前链表的原始链表节点的next指向原始next(此时是其复制节点的next) listNode.next = copyNode.next; // 移动当前链表的指针,此时为复制链表的头节点 listNode = listNode.next; } while (listNode != null) { // 复制链表节点的next改为当前节点的next // a -> a1 -> b -> b1,变回 a1 -> b1 copyNode.next = listNode.next; // 移动复制链表的指针 copyNode = copyNode.next; // 将原始链表中的节点的next指向原始next(此时是其复制节点的next) // a -> a1 -> b -> b1,变回 a -> b listNode.next = copyNode.next; // 移动当前链表的指针,此时遍历的是原始链表 listNode = listNode.next; } return copyHead; } public static ListNode cloneNode(ListNode head) { if (head == null) { return null; } copy(head); setOther(head); return disConnect(head); } public static void main(String[] args) { ListNode root = bulidList(); ListNode copy = cloneNode(root); while (root != null) { System.out.println(root.toString()); root = root.next; } while (copy != null) { System.out.println(copy.toString()); copy = copy.next; } } private static ListNode bulidList() { ListNode node1 = new ListNode(1); ListNode node2 = new ListNode(2); ListNode node3 = new ListNode(3); ListNode node4 = new ListNode(4); ListNode node5 = new ListNode(5); node1.next = node2; node2.next = node3; node3.next = node4; node4.next = node5; node1.other = node3; node4.other = node1; return node1; }