2019-11-20

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

思路:


这里需要注意一下Java的复制引用和复制(克隆)对象的区别,具体查看https://www.cnblogs.com/kexianting/p/8505056.html
引用和对象

/*
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)
    {
        if(pHead == null){
            return null;
        }
        
        //第一步,从到位将所有的结点都复制一遍,复制出来的新节点放在原结点和原结点的next结点之间
        //这里得说明一下,currentNode和pHead是两个引用,各自指向内存中的一块内存的地址,
        //用pHead给currentNode赋值,是为了让currentNode这个引用指向pHead所指向的那个内存地址
        //后面currentNode不断后移,其指向的地址不断的变化,但是pHead指向的地址没有变
        RandomListNode currentNode = pHead;
        while(currentNode != null){
            //clone一份currentNode节点
            //这里需要新建一个RandomListNode对象,而不能像上面那种情况直接复制,那样只是创建了同一个对象的一个新的引用
            RandomListNode cloneNode = new RandomListNode(currentNode.label);
            cloneNode.next = currentNode.next;//将clone出来的新节点的next指针指向currentNode结点的next结点
            currentNode.next = cloneNode;//将currentNode结点的next指针指向clone出来的新节点
            currentNode = cloneNode.next;//更新currentNode结点
        }
        
        //第二步,将所有clone出来的结点的random指向其clone对象结点的random指针指向的结点的next结点
        //先将currentNode结点引用指向的地址还原为pHead引用指向的地址
        currentNode = pHead;
        while(currentNode != null){
            //将clone出来的结点的random指向其clone对象结点的random指针指向的结点的next结点
            if(currentNode.random == null){
                currentNode.next.random = null;
            }else{
                currentNode.next.random = currentNode.random.next;
            }
            //更新currentNode引用
            currentNode = currentNode.next.next;
        }
        
        //第三步,将所有复制的结点所组成的链表和原链表分离开来
        //先将currentNode结点引用指向的地址还原为pHead引用指向的地址
        currentNode = pHead;
        //复制新的头结点的引用
        RandomListNode cloneHead = pHead.next;
        while(currentNode != null){
            RandomListNode cloneNode = currentNode.next;
            currentNode.next = cloneNode.next;
            //如果cloneNode的next结点是最后一个结点,则新链表的cloneNode的next结点应是next结点,这里注意判断一下这个终止情况
            cloneNode.next = cloneNode.next == null ? null : cloneNode.next.next;
            currentNode = currentNode.next;
        }
         
        return cloneHead;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容