复杂链表的复制

题目

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)


我的思路

一开始我是没有什么思路的,唯一能想到的就是先将所有的节点复制下来,然后再确定每一个节点的random节点。不过,这种做法实在是很蠢,在提交通过了之后,看到评论上的做法才知道,原来还可以这么玩的~


无任何技术含量版

代码如下

public RandomListNode Clone(RandomListNode pHead)
{
    if (pHead == null) return null;

    RandomListNode newHead = new RandomListNode(pHead.label);
    RandomListNode node = newHead;
    RandomListNode lastNode = pHead;
    RandomListNode copyPHead = pHead;
    RandomListNode newLast = newHead;
    RandomListNode copyNewHead = newHead;

    while (pHead.next != null) {
        pHead = pHead.next;
        RandomListNode newNode = new RandomListNode(pHead.label);
        node.next = newNode;
        node = newNode;
    }
    node.next = null;

    pHead = copyPHead;

    while (lastNode != null) {
        RandomListNode random = lastNode.random;

        while (copyPHead != null) {
           if (copyPHead == random) {
               newLast.random = copyNewHead;
               break;
           }
           copyPHead = copyPHead.next;
           copyNewHead = copyNewHead.next;
        }

        lastNode = lastNode.next;
        newLast = newLast.next;
        copyPHead = pHead;
        copyNewHead = newHead;
    }
    return newHead;
}

推荐版

这个做法的思路分为三步,分别是:复制,确定random节点,分离。

  1. 复制每个节点,并且把复制的每个节点插在被复制节点的后面。
    就像这样 A->B->C ==> A->A`->B->B`->C->C`
  2. 新链表中每个节点的random节点必定在原链表中对应节点的random节点的后面。
    比如:A的random节点是C,那么有A`的节点是C`,并且C`在C的后面
  3. 将原链表和新链表分离

代码如下

public RandomListNode Clone(RandomListNode pHead)
{
    if (pHead == null) return null;

    RandomListNode pCur = pHead;

    //复制链表
    while (pCur != null) {
        RandomListNode node = new RandomListNode(pCur.label);
        node.next = pCur.next;
        pCur.next = node;
        pCur = node.next;
    }

    pCur = pHead;

    //设置每个新节点的random节点
    while (pCur != null) {
        if (pCur.random != null)
            pCur.next.random = pCur.random.next;
        pCur = pCur.next.next;
    }

    RandomListNode newHead = pHead.next;
    RandomListNode newCur = newHead;
    pCur = pHead;

    //分离两个链表
    while (pCur != null) {
        pCur.next = pCur.next.next;
        if (newCur.next != null)
            newCur.next = newCur.next.next;
        newCur = newCur.next;
        pCur = pCur.next;
    }

    return newHead;
}
posted @ 2018-05-03 09:14  _weirdly  阅读(70)  评论(0编辑  收藏  举报