复杂链表的复制

来源:互联网 发布:淘宝逆战解封 编辑:程序博客网 时间:2024/06/17 04:37

题目描述

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

摘要: 题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

思路1:因为next指针是固定的,在复制的时候这点比较好处理,由于特殊指针是任意的,可能是在节点之前,也可能在节点之后,所以必须解决这个棘手问题。不管至少,可以从链表的第一个节点开始遍历,直到该特殊指针指向的节点,并设置该节点的特殊指针。这种做法的时间复杂度稍微有点大。

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

思路2

第一步,复制原来链表的节点,并设置next指针,这一步不同于简单的复制节点,而是把每个复制的节点都链在原节点的后面,相当于复制节点之间隔了一个原节点;

第二步,设置复制节点的特殊指针,由于在第一步做了特殊处理,所以当一个节点R的特殊指针指向节点N的时候,复制节点R’的特殊指针则是N’,这样就可以在O(1)时间定位到R的特殊指针指向的节点;

第三步,从链表中抽取出复制节点,由于复制节点是间隔相连的,所以这一步比较好处理。

综合以上三个步骤,就完成了复杂链表的复制。

注意:链表的操作无非就是将链结点正确的前后相连起来就行,只要按照准则去处理链表之间的指针引用指向正确的链结点即可。

代码:

package JianZhiOffer;
  class RandomListNode
  {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label)
    {
        this.label = label;
    }
 }


public class ListNodeClone
{
     public RandomListNode Clone(RandomListNode pHead)
     {
         if(pHead==null)
             return null;
         cloneNodes(pHead);
         connectRandomNodes(pHead);
        return connectFinalListNodes(pHead);
    }

    private void cloneNodes(RandomListNode pHead)
    {
        RandomListNode node=pHead;
        while(node!=null)
        {
            RandomListNode cloneNode=new RandomListNode(node.label);
            cloneNode.next=node.next;
            cloneNode.random=null;
            
            node.next=cloneNode;
            node=cloneNode.next;
        }
    }

    private RandomListNode connectRandomNodes(RandomListNode pHead)
    {
        RandomListNode node=pHead;
        while(node!=null)
        {
            RandomListNode cloneNode=node.next;
            if(node.random!=null)
            {
                cloneNode.random=node.random.next;
                
            }
            node=cloneNode.next;
        }
        return pHead;    
    }

    private RandomListNode connectFinalListNodes(RandomListNode pHead)
    {
        RandomListNode node=pHead;
        RandomListNode cloneHead=null;
        RandomListNode cloneNode=null;
        if(node!=null)
        {
            cloneHead=node.next;
            cloneNode=node.next;
            node.next=cloneNode.next;
            node=node.next;
        }
        while(node!=null)
        {
            cloneNode.next=node.next;
            cloneNode=cloneNode.next;
            node.next=cloneNode.next;
            node=node.next;
        }
        return cloneHead;
    }

    public static void main(String[] args)
    {
        RandomListNode pHead = new RandomListNode(1);
        RandomListNode node1 = new RandomListNode(2);
        RandomListNode node2 = new RandomListNode(3);
        RandomListNode node3 = new RandomListNode(4);
        RandomListNode node4 = new RandomListNode(5);
        RandomListNode node5 = new RandomListNode(6);
        RandomListNode node6 = new RandomListNode(7);
        RandomListNode node7 = new RandomListNode(8);

        pHead.next = node1;
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;

        pHead.random = node4;
        node2.random = node6;

        @SuppressWarnings("unused")
        RandomListNode node = new ListNodeClone().Clone(pHead);
        System.out.println(node);
    }
}


原创粉丝点击