劍指offer面試題26:複雜鏈表的複製Java實現

題目描述:

一個複雜鏈表,在複雜鏈表中,每個結點除了有一個next指針指向下一個結點外,還有一個sbiling指向鏈表中的任意結點或者null。

下圖是一個複雜鏈表的示例,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;
        }

    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章