复杂链表的复制

来源:互联网 发布:安卓手机php服务器 编辑:程序博客网 时间:2024/05/16 08:56

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。、

如图
是一个含有 5 个结点的复杂链表。图中实线箭头表示 next 指针,虚线箭头表示 sibling 指针。为简单起见,指向 null 的指针没有画出。
这里写图片描述

在不用辅助空间的情况下实现 O(n)的时间效率。

思路:

  1. 根据原始链表的每个结点N 创建对应的 N’。把 N’链接在N的后面
  2. 设置复制出来的结点的 sibling。假设原始链表上的 N 的 sibling 指向结点 S,那么其对应复制出来的 N’是 N的 pext 指向的结点,同样 S’也是 S 的 next 指向的结点
  3. 把这个长链表拆分成两个链表。把奇数位置的结点用 next 链接起来就是原始链表,把偶数位置的结点用 next 链接起来就是复制 出来的链表。图 4.10 中的链表拆分之后的两个链表

这里写图片描述
这里写图片描述
这里写图片描述

    public static ComplexListNode clone(RandomListNode head) {        // 如果链表为空就直接返回空        if (head == null) {            return null;        }        // 先复制结点        cloneNodes(head);        // 再链接sibling字段        connectNodes(head);        // 将整个链表拆分,返回复制链表的头结点        return reconnectNodes(head);    }    /**     * 复制一个链表,并且将复制后的结点插入到被复制的结点后面,只链接复制结点的next字段     *     * @param head 待复制链表的头结点     */    public static void cloneNodes(RandomListNode head) {         RandomListNode node=head;        while (node!=null){            RandomListNode complexListNode = new RandomListNode(node.label);            complexListNode.label=node.label;            complexListNode.next=node.next;            complexListNode.random=node.random;            node.next=complexListNode;            node=complexListNode.next;        }    }    /**     * 设置复制结点的sibling字段     *     * @param head 链表的头结     */    public static void connectNodes(ComplexListNode head) {          RandomListNode node=head;        while (node!=null){            RandomListNode pClone=node.next;            if (node.random!=null){                pClone.random=node.random.next;            }            node=pClone.next;        }    }    /**     * 刚复制结点和被复制结点拆开,还原被复制的链表,同时生成监制链表     *     * @param head 链表的头结点     * @return 复制链表的头结点     */    public static RandomListNode reconnectNodes(RandomListNode head) {         RandomListNode pnode=head;        RandomListNode pCloneHead=null;        RandomListNode pCloneNode=null;        if (pnode!=null){            pCloneHead=pCloneNode=pnode.next;            pnode.next=pCloneNode.next;            pnode=pnode.next;        }        if (pnode!=null){           pCloneNode.next=pnode.next;            pCloneNode=pCloneNode.next;            pnode.next=pCloneNode.next;            pnode=pnode.next;        }        return pCloneHead;    }
0 0