算法——复杂链表的复制(插入中点法)

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
链接:leetcode

解题思路:不同于简单列表的复制,这个多了一个随机指针。如果是简单列表,直接构造一个新的列表,将老链表遍历复制数据就好了。但是,随机指针就不能这么做了,因为随机指针指向的可能是还没有遍历的到节点,那就没法指了。

所以,一种思路是这样的。三次遍历,第一次遍历,复制一个新的节点到每两个旧节点中间。第二次遍历,将新节点的随机指针指向被复制的旧节点的随机指针的下一个节点(看代码就懂了)。第三次遍历,将新旧节点分开,得到两个新旧链表。

需要注意的问题,在第二次遍历的时候,复制随机节点可能是null的,如果是null,那就直接将随机指针置为null就好了。

在第三次遍历的时候,需要预判是不是到了尾节点,这样就能把新链表的尾节点的next指向null。

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return head;

        Node cur = head;

        while(cur != null) {
            Node temp = cur.next;
            cur.next = new Node(cur.val);
            cur.next.next = temp;
            cur = temp;
        }

        cur = head;
        while(cur != null) {
            cur.next.random = cur.random == null ? null : cur.random.next;
            cur = cur.next.next;
        }

        cur = head;
        Node res = cur.next;
        while(cur != null) {
            Node temp = cur.next;
            cur.next = temp.next;
            temp.next = cur.next == null ? null : cur.next.next;
            cur = cur.next;
        }

        return res;

    }
}
原文地址:https://www.cnblogs.com/lippon/p/14117671.html