複雜鏈表的複製

題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的頭結點。
思路:
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-->32-->43-->14-->25--> null, 6-->5, 
clone的鏈表的random指針
1-->32-->43-->14-->25--> null, 6-->5
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章