題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的頭結點。
思路:
1. 首先根據鏈表的next遍歷一遍,在每個node節點的後面複製一個與node的label相等的節點,如圖所示;
2. 再遍歷新鏈表,爲複製的節點指定random指針(黃色箭頭所示);
3. 將新鏈表拆分=原鏈表+複製後的鏈表
4. 在操作過程中一定要主要判斷節點是否爲空
5. 時間複雜度o(n),空間複雜度o(n)
示例代碼如下:
/**
* Copyright (C), 2017
* FileName: Main
* Author: Mengjun Li
* Date: 2017/10/3 上午11:09
* Description:
*/
/**
* @author Mengjun Li
* @create 2017/10/3
* @since 1.0.0
*/
public class Main {
public static void main(String args[]) {
//定義測試節點
RandomListNode node1 = new RandomListNode(1);
RandomListNode node2 = new RandomListNode(2);
RandomListNode node3 = new RandomListNode(3);
RandomListNode node4 = new RandomListNode(4);
RandomListNode node5 = new RandomListNode(5);
RandomListNode node6 = new RandomListNode(6);
node1.next = node2;
node1.random = node3;
node2.next = node3;
node2.random = node4;
node3.next = node4;
node3.random = node1;
node4.next = node5;
node4.random = node2;
node5.next = node6;
node5.random = null;
node6.random = node5;
System.out.println("原鏈表的next指針");
while (head != null) {
System.out.print(head.label + "-->");
head = head.next;
}
System.out.println("null");
//Clone鏈表
head = Clone(node1);
System.out.println("clone的鏈表的next指針");
while (head != null) {
System.out.print(head.label + "-->");
head = head.next;
}
System.out.println("null");
System.out.println("原鏈表的random指針");
head = node1;
while (head != null) {
if (head.random != null)
System.out.print(head.label + "-->"+head.random.label+", ");
else
System.out.print(head.label + "--> null, ");
head = head.next;
}
System.out.println("");
head = Clone(node1);
System.out.println("clone的鏈表的random指針");
while (head != null) {
if (head.random != null)
System.out.print(head.label + "-->"+head.random.label+", ");
else
System.out.print(head.label + "--> null, ");
head = head.next;
}
}
public static RandomListNode Clone(RandomListNode pHead) {
if (pHead == null)
return pHead;
RandomListNode tmp = null, oHead = pHead, newNode;
//第一步:在原鏈表中每一個節點的後面複製前面一個節點
while (oHead != null) {
newNode = new RandomListNode(oHead.label);
tmp = oHead.next;
oHead.next = newNode;
newNode.next = tmp;
oHead = tmp;
}
oHead = pHead;
//第二步:給複製的節點的random指針賦值
while (oHead != null) {
if (oHead.random != null)//random可能爲null
oHead.next.random = oHead.random.next;
else
oHead.next.random = null;
oHead = oHead.next.next;
}
//將複製後的鏈表和原鏈表斷開
oHead = pHead;
newNode = pHead.next;
while (oHead != null) {
tmp = oHead.next;
if (tmp != null)
oHead.next = tmp.next;
oHead = tmp;
}
return newNode;
}
}
class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
輸出如下:
原鏈表的next指針
1-->2-->3-->4-->5-->6-->null
clone的鏈表的next指針
1-->2-->3-->4-->5-->6-->null
原鏈表的random指針
1-->3, 2-->4, 3-->1, 4-->2, 5--> null, 6-->5,
clone的鏈表的random指針
1-->3, 2-->4, 3-->1, 4-->2, 5--> null, 6-->5,