題目描述:
一個複雜鏈表,在複雜鏈表中,每個結點除了有一個next指針指向下一個結點外,還有一個sbiling指向鏈表中的任意結點或者null。
解題思路:
1.很直觀的解法就是分成兩步:
1).原始鏈表上的每一個結點,並用next指針連起來。
2).sbiling指針。
但是sbiling指針時需要比較高的複雜度。
以上圖爲例,如果我們要B對應B’的的sbiling指針,那就是要找到E’,想要找到E’只能根據 B到E要走的步數 = B’到E’要 走的步數 然而又如D.sbiling = B,指向的結點在它的前面,而鏈表並沒有指向前一個元素的指針,所以,每次都只能根據從鏈 表頭結點到目標的結點的步數來找到sbiling應該指向的元素。 這種方法顯然效率太低,時間複雜度達到了O(n*n)。
2.書中提到了利用哈希表存儲(N, N’)的配對信息的方法
這是一個在時間上很高效的方法,在查找上,利用哈希表的高效性。但是缺點在於要用額外的空間。
3.更爲高效的一種不利用輔助空間的方法
這個方法的巧妙之處在於利用鏈表結點本身記錄sbiling指針的位置。
分成三個步驟
1).根據原始鏈表的每個結點N創建對應的N’,並把N’連在N的後面。
如下圖:
2)看到上圖我們就應該知道這個算法的巧妙之處了,B’.sbiling就記錄在B.sbiling.next,這一步就是通過這個方法設置sbiling指針了。
3).將兩個鏈表斷開。
代碼如下:
public class CopyComplexListTest {
static class Node{
int value;
Node next;
Node sbiling;
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("value = " + value);
sb.append(", next = " + (next == null ? "null" : next.value));
sb.append(", sbiling = " + (sbiling == null ? "null" : sbiling.value));
return sb.toString();
}
}
public static void copyList(Node head){
Node node = head;
while(node != null){
Node copyNode = new Node();
copyNode.value = node.value;
copyNode.next = node.next;
copyNode.sbiling = null;
node.next = copyNode;
node = copyNode.next;
}
}
public static void setSbiling(Node head){
Node node = head;
while(node != null){
Node copyNode = node.next;
if(node.sbiling != null){
copyNode.sbiling = node.sbiling.next;
}
node = copyNode.next;
}
}
public static Node disConnectList(Node head){
Node node = head;
Node copyHead = null;
Node copyNode = null;
if(node != null){
copyHead = node.next;
copyNode = node.next;
node.next = copyNode.next;
node = node.next;
}
while(node != null){
copyNode.next = node.next;
copyNode = copyNode.next;
node.next = copyNode.next;
node = node.next;
}
return copyHead;
}
public static Node copy(Node head){
copyList(head);
setSbiling(head);
return disConnectList(head);
}
public static void main(String[] args) {
Node head = new Node();
head.value = 1;
Node node2 = new Node();
node2.value = 2;
Node node3 = new Node();
node3.value = 3;
Node node4 = new Node();
node4.value = 4;
Node node5 = new Node();
node5.value = 5;
head.next = node2;
head.sbiling = node3;
node2.next = node3;
node2.sbiling = node5;
node3.next = node4;
node4.next = node5;
node4.sbiling = node2;
Node copyHead = copy(head);
Node node = copyHead;
while(node != null){
System.out.println(node);
node = node.next;
}
}
}