剑指offer第25题(C#)

剑指offer第25题(C#)

题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

这道题目的主要是能够把逻辑梳理清楚,我采用的的方法是网上流行的解法,将整个链表复制然后再分割返回深拷贝后的复杂链表。借用网友做的三张图

可以很直观的看出原链表插入复制第一步就是将链表中的next复制插入一遍。
在这里插入图片描述
接下来就是把random给复制和穿插起来,第二步需要依靠第一步复制之后的链表才能继续复制关系。(代码中我会详细解释)
在这里插入图片描述
最后将复制出来的大链表分割开来把后者返回输出。好了大致的逻辑是这样的我们来看看代码实现吧:下面展示一些 内联代码片

    public RandomListNode Clone(RandomListNode pHead)
    {
    
    
        // write code here
        if(pHead==null)
           return null;       
        RandomListNode head = pHead;
        RandomListNode head2 = pHead;//这里将头节点复制两遍在后面复制两块逻辑用上        
        while(pHead!=null)
        {
    
    
            RandomListNode res = new RandomListNode(pHead.label);
            res.next = pHead.next;
            pHead.next = res;
            pHead = res.next;//第一部分的模块链表建议大家参照第一张图片配合食用效果更佳,就是简单的单链表插入操作。
        }
        while(head!=null)
        {
    
    
            if(head.random!=null)
                head.next.random = head.random.next;//原来的节点指向的random赋值到复制之后A’节点的random去
            head = head.next.next;//第二部分复制random模块,同样建议大家配合第二张图食用,
            //利用第一段代码的基础下把原来的节点指向的random赋值到复制之后A’节点的random去。
        }
        RandomListNode head3 = head2.next;//head3赋值为复制之后的链表头节点做输出头节点。
        RandomListNode result = head3;//从result来开始拼接起来整个深拷贝链表的每个节点。
        head = head2;//从重合的大链表头指针开始循环切分
        while(head!=null)
        {
    
    
            head.next = head.next.next;//原链表两个两个一切之后缝合。
            if(result.next!=null)
                result.next = result.next.next;//深拷贝链表两个两个一切之后缝合。
            head = head.next;
            result = result.next;//循环递增指向下一个两个分链表各自节点。
        }        
        return head3;
    }

这道题目主要在于那三张图的逻辑,把三个步骤的逻辑都思考和理清楚了,一个一个步骤实现下去就能解决了,其中并没有涉及太多的语法和链表的方法使用,比较考验大家的逻辑算法能力。

猜你喜欢

转载自blog.csdn.net/weixin_50746193/article/details/116657746