复制复杂链表

题目:

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


解题思路:
首先有三种解法:
第一种就是中规中矩的解法,首先复制next指针的节点,之后再复制random指针的节点,这种解法的缺点是时间复杂度太高,O(n^2).


第二种思路就是以空间换时间,设置一个HashMap用来存储每一个链表的节点,<key, value> 分别为原链表节点、新链表节点,复制的过程还是分两步完成,第一步就是顺着next依次复制,第二步就是复制random指针,如果原链表random指针不为空则从map中取出来,然后设置对应新链表的节点,这样空间复杂度为O(n), 时间复杂度为O(n)。


第三种思路就是在不用辅助空间的情况下实现O(n)的解法,大体步骤还是第二种思路那样两步,不同的是第一步顺着next走的时候我们复制出来的新节点紧接着插入对应的旧节点后面,第二步再复制random指针。最后一步就是将链表拆分成新链表和旧链表两个部分。

代码:

第二种思路代码:

public RandomListNode Clone(RandomListNode pHead) {
    if (pHead == null) {
        return null;
    }
    RandomListNode p = pHead;
    RandomListNode head = new RandomListNode(-1);
    RandomListNode q = head;
    HashMap<RandomListNode, RandomListNode> hash = new HashMap<>();
    while (p != null) {
        RandomListNode tmp = new RandomListNode(p.label);        
        hash.put(p, tmp);
        q.next = tmp;

        q = q.next;
        p = p.next;
    }
    //q = head.next;
    p = pHead;
    while (p != null) {
        if (p.random != null) {
            RandomListNode value = hash.get(p);
            RandomListNode random = hash.get(p.random);
            value.random = random;
        }
        p = p.next;
    }
    return head.next;
}


第三种思路代码:

public static RandomListNode copyRandomList(RandomListNode pHead) {
    if (pHead == null) {
        return null;
    }
    //复制并且插入
    RandomListNode p = pHead;
    while (p != null) {
        RandomListNode tmp = new RandomListNode(p.label);
        tmp.next = p.next;
        p.next = tmp;
        
        p = tmp.next;
    }
    //复制random指针
    p = pHead;
    while (p != null) {
        if (p.random != null) {
            p.next.random = p.random.next;
        }
        p = p.next.next;
    }
    //拆分链表
    
    RandomListNode head = pHead.next;
    RandomListNode q = head;
    p = pHead;
    //这个部分需要注意一下
    while (q.next != null) {
        p.next = q.next;
        p = p.next;
        
        q.next = p.next;
        q = q.next;
    }
    p.next = null;  //最后将原来链表的尾部设置为null
    return head;
}
---------------------  
作者:will_duan  
来源:CSDN  
原文:https://blog.csdn.net/willduan1/article/details/53352759  
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/wojiuguowei/article/details/83959908
今日推荐