链表之复杂链表的复制

1.本题知识点

   链表,复杂问题分解,复制

2. 题目描述

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

3. 思路

   主要分3部分:
   ① 复制链表中的每一个节点

链表之复杂链表的复制_第1张图片

   ② 原链表中A指向C,那么新复制的节点A’也指向 C’。

链表之复杂链表的复制_第2张图片

   ③ 拆分长链表,偶数位置上的节点用next连接起来就是复制出来的链表。

链表之复杂链表的复制_第3张图片

   Java版本:
/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        cloneNode(pHead);
        updateRandomCloneNode(pHead);
        return splitListNode(pHead);
    }
    
    /**
     * 复制原链表
    */
    public void cloneNode(RandomListNode pHead){
        RandomListNode pNode = pHead;
        while(pNode != null){
            //复制当前节点
            RandomListNode cloneNode = new RandomListNode(pNode.label);
            cloneNode.next = pNode.next;//复制的节点指向原节点的next节点
            cloneNode.random = null;//复制节点的random指针暂时指向为空
            
            pNode.next = cloneNode;//原节点next指向复制节点
            //相当于移动指针操作:已复制完一个节点,转向下一个节点
            pNode = cloneNode.next;
        }
    }
    
    /**
     * 根据原节点的random指针更新复制节点的random
    */
    public void updateRandomCloneNode(RandomListNode pHead){
        RandomListNode curNode = pHead;//当前节点
        while(curNode != null){
            RandomListNode cloneNode = curNode.next;
            //若原节点的random不为空,则更新复制节点的random
            if(curNode.random != null){
                cloneNode.random = curNode.random.next;
            }
            //相当于移动指针操作:已判断完一个节点,转向下一个节点
            curNode = cloneNode.next;
        }
    }
    
   /**
     * 拆分链表,
    */
    public RandomListNode splitListNode(RandomListNode pHead){
        RandomListNode curNode = pHead;//当前节点
        RandomListNode pCloneHead = null;//新节点head
        RandomListNode pCloneNode = null;//新节点指针
        //初始化
        if(curNode != null){
            //这个地方注意 pCloneHead 和 pCloneNode指针同时指向一个地址,
            //遍历时只移动pCloneNode指针,pCloneHead不变
            pCloneHead = pCloneNode = curNode.next;
            curNode.next = pCloneNode.next;
            curNode = curNode.next;
        }
        //注意,有4个指针:当前节点指针和其next指针,新节点指针和其next指针
        //在遍历过程中都要操作这4个指针,其中移动指针是为了继续循环
        while(curNode != null){
            //改变clone节点的next指针
            pCloneNode.next = curNode.next;
            //移动clone节点指针
            pCloneNode = pCloneNode.next;
            //改变当前节点的next指针
            curNode.next = pCloneNode.next;
            //移动当前节点指针
            curNode = curNode.next;
        }
        
        return pCloneHead;
    }
}





你可能感兴趣的:(数据结构和算法,复杂链表的复制)