算法练习篇之:复杂链表的复制

算法练习篇之:复杂链表的复制

题目描述

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

解题思路

本题思路共分为三个阶段:
阶段一:链表节点的复制
本阶段只需将链表的每个节点复制一次,方法很简单A->B 变为A->A’->B,每次都产生一个新的节点,依次插在原链表每个节点的后面,A‘即为新产生的点。插入操作也是链表的常见操作!
阶段二:还原复制的每个节点的特殊指针指向
因为每个节点有两个指针,第一阶段,我们完成了节点复制,但是其每个节点的特殊指针指向,我们还没有定义,其实复制节点的特殊指针(random指针)指向,为原来本节点的random指针指向节点的下一节点。读者看下面示意图看是否是这么个道理。
阶段三:拆分两个链表
上面两个阶段,我们已经完成的差不多了,接下来需要做的就是分离工作。奇数个节点为本链表,偶数个节点为复制链表,依据这个思想我们可以逐步分离,代码写的比较详细!

图示

阶段一:把复制的结点链接在原始链表的每一对应结点后面
在这里插入图片描述
阶段二:把复制的结点的random指针指向被复制结点的random指针的下一个结点
在这里插入图片描述
阶段三:拆分成两个链表,奇数位置为原链表,偶数位置为复制链表
在这里插入图片描述

代码实现

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.


class complexListNode{
    int val;
    complexListNode next;
    complexListNode random;
}
public class copyComplexList {
    //复制复杂链表
    public void cloneNodes(complexListNode pHead){//第一步:复制节点
        complexListNode pNode=pHead;
        while (pNode!=null){
            complexListNode pClone=new complexListNode();
            pClone.val=pNode.val;
            pClone.next=pNode.next;
            pClone.random=null;
            pNode.next=pClone;
            pNode=pClone.next;
        }
    }

    public void connectRandomNodes(complexListNode pHead){//第二步:将复制后节点的随机指针连接完成
        complexListNode pNode=pHead;
        while (pNode!=null){
            complexListNode pClone=pNode.next;
            if (pNode.random!=null){
                pClone.random=pNode.random.next;
            }
            pNode=pClone.next;
        }
    }

    complexListNode reconnectNodes(complexListNode pHead){//第三步:拆分链表
        complexListNode pNode=pHead;
        complexListNode pCloneHead=pHead.next;

        while (pNode!=null){
            complexListNode pClone=pNode.next;
            pNode.next=pClone.next;
            pClone.next=pClone.next==null?null:pClone.next.next;//此处需要注意,如果循环至链表最后一组节点则会出现next为空,
                                                                //所以pclone.next.n错
            pNode=pNode.next;

        }
        return pCloneHead;
    }
    complexListNode clone(complexListNode pHead){
        cloneNodes(pHead);
        connectRandomNodes(pHead);

        return reconnectNodes(pHead);
    }


    public static void main(String[] args) {
        complexListNode node1=new complexListNode();
        complexListNode node2=new complexListNode();
        complexListNode node3=new complexListNode();
        complexListNode node4=new complexListNode();
        complexListNode node5=new complexListNode();

        node1.val=11; node1.next=node2; node1.random=node4;
        node2.val=21; node2.next=node3; node2.random=node5;
        node3.val=31; node3.next=node4; node3.random=node1;
        node4.val=41; node4.next=node5; node4.random=node2;
        node5.val=51; node5.next=null;  node5.random=node3;

        copyComplexList test=new copyComplexList();
        complexListNode node = test.clone(node1);
        System.out.println(node.val+" "+node.random.val+" "+node.next.next.val);


    }
}



总结

本题来源于面试经典教材《剑指offer》中 归属于链表类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
最后,感谢Jerry算法!

明天开始比赛,这周先断更几天,下周多更新几次!!!!!!!!!
加油 冲冲冲!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值