復雜鏈表的復制——牛客offer


題目描述:

輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)

數據結構:

public class RandomListNode {
    int label;                                             數據域
    RandomListNode next = null;            指向下一個結點
    RandomListNode random = null;       指向任意一個節點

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

解題思路:

1、遍歷鏈表,復制鏈表中的每個結點,並將復制的結點插入到該結點的后面。例如,原鏈表為A->B->C, 遍歷完畢后,鏈表變為A->A'->B->B'->C->C',其中A‘,B',C'是結點A,B,C的復制結點。

看圖中,藍色箭頭為next指針:

 

復制結點后:

2、為復制結點的random指針賦值

如果原結點的random指針指向的是結點B,那么將復制結點的random指針指向結點B的復制結點B'。

圖中黑色箭頭為random指針:

復制結點的random指針賦值后:

3、將鏈表的原始結點與復制結點分割至兩個鏈表,使原始結點構成一個鏈表,復制結點構成一個鏈表。

 

代碼實現:

1、復制結點

 //1.加入copy結點
public void copyNodes(RandomListNode pHead){ RandomListNode walkNode=pHead; while(walkNode!=null){ RandomListNode cloneNode=new RandomListNode(walkNode.label); cloneNode.next=walkNode.next; walkNode.next=cloneNode; walkNode=cloneNode.next; } }

2、為復制結點的random指針域賦值

//2.為新copy結點的random域指定值
    public void initRandom(RandomListNode pHead){ RandomListNode walkNode=pHead; RandomListNode cwalkNode=pHead; while(walkNode!=null){ cwalkNode=walkNode.next; if(walkNode.random!=null){ cwalkNode.random=walkNode.random.next; } walkNode=cwalkNode.next; } }

3、將結點和復制結點分為兩個鏈表

//3.將鏈表和其copy版本分為兩個鏈表
     public RandomListNode split2list(RandomListNode pHead){ RandomListNode cpHead=pHead.next; RandomListNode walkNode=pHead; RandomListNode cwalkNode=cpHead; while(walkNode!=null){ walkNode.next=cwalkNode.next; walkNode=walkNode.next; if(walkNode==null){ cwalkNode.next=null; } else{ cwalkNode.next=walkNode.next; cwalkNode=cwalkNode.next; } } return cpHead; }

4、總的調用函數

public RandomListNode Clone(RandomListNode pHead) { if(pHead==null){ return null; } copyNodes(pHead); initRandom(pHead); return split2list(pHead); }

全部代碼

 1 class RandomListNode {  2     int label;  3     RandomListNode next = null;  4     RandomListNode random = null;  5     RandomListNode(int label) {  6         this.label = label;  7  }  8 }  9 
10 public class copyList { 11      //1.加入copy結點
12     public void copyNodes(RandomListNode pHead){ 13         RandomListNode walkNode=pHead; 14          while(walkNode!=null){ 15              RandomListNode cloneNode=new RandomListNode(walkNode.label); 16              cloneNode.next=walkNode.next; 17              walkNode.next=cloneNode; 18              walkNode=cloneNode.next; 19  } 20  } 21     //2.為新copy結點的random域指定值
22      public void initRandom(RandomListNode pHead){ 23          RandomListNode walkNode=pHead; 24          RandomListNode cwalkNode=pHead; 25          while(walkNode!=null){ 26              cwalkNode=walkNode.next; 27              if(walkNode.random!=null){ 28                  cwalkNode.random=walkNode.random.next; 29  } 30              walkNode=cwalkNode.next; 31  } 32  } 33     //3.將鏈表和其copy版本分為兩個鏈表
34      public RandomListNode split2list(RandomListNode pHead){ 35          RandomListNode cpHead=pHead.next; 36          RandomListNode walkNode=pHead; 37          RandomListNode cwalkNode=cpHead; 38          while(walkNode!=null){ 39              walkNode.next=cwalkNode.next; 40              walkNode=walkNode.next; 41              if(walkNode==null){ 42                  cwalkNode.next=null; 43  } 44              else{ 45                  cwalkNode.next=walkNode.next; 46                  cwalkNode=cwalkNode.next; 47  } 48  } 49          return cpHead; 50  } 51      public RandomListNode Clone(RandomListNode pHead) 52  { 53          if(pHead==null){ 54              return null; 55  } 56  copyNodes(pHead); 57  initRandom(pHead); 58          return split2list(pHead); 59  } 60      public static void main(String[]args){ 61             RandomListNode head = new RandomListNode(1);
63             RandomListNode node2 = new RandomListNode(2);
65             RandomListNode node3 = new RandomListNode(3);
67             RandomListNode node4 = new RandomListNode(4);
69             RandomListNode node5 = new RandomListNode(5); 70             head.next = node2; 71             node2.next = node3; 72             node3.next = node4; 73             node4.next = node5; 74             head.random = node3; 75             node2.random = node5; 76             node4.random = node2; 77             copyList s = new copyList(); 78             RandomListNode copyList=s.Clone(head); 79             System.out.print(copyList.label + " "); 80 // while (copyList != null) 81 // { 82 // System.out.print(copyList.label + " ") 83 // copyList = copyList.next; 84 // }
85  } 86 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM