有隨機指針的鏈表複製

原題

  A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
  Return a deep copy of the list.node

題目大意

  一個單鏈表包含一個指向任意結點或者null的結點指針,返回這個鏈表的深拷貝算法

解題思路

  第一步:複製結點,複製的結點放在待複製的結點後,依然組成一個單鏈表
  第二步:串接隨機指針
  第三步:鏈表拆分。拆成原鏈和複製鏈dom

代碼實現

結點類this

class RandomListNode {
    int label;
    RandomListNode next, random;
    RandomListNode(int x) { this.label = x; }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

算法實現類spa

public class Solution {

    public RandomListNode copyRandomList(RandomListNode head) {
        if (head == null) {
            return null;
        }

        copyNode(head);
        linkRandomPointer(head);

        return splitList(head);
    }

    /**
     * 複製結點,複製的結點放在待複製的結點後,依然組成一個單鏈表
     *
     * @param head 鏈表頭
     */
    public void copyNode(RandomListNode head) {
        // 記錄當前要被複制的縝
        RandomListNode node = head;
        while (node != null) {
            // 複製一個新的結點
            RandomListNode copyNode = new RandomListNode(node.label);
            // 將結點串接到被複制的結點後,而且依然組成單鏈表
            copyNode.next = node.next;
            node.next = copyNode;
            node = copyNode.next;
        }
    }

    /**
     * 串接隨機指針
     *
     * @param head 鏈表頭
     */
    public void linkRandomPointer(RandomListNode head) {
        // 記錄當前要被複制的縝
        RandomListNode node = head;
        while (node != null) {
            // 隨機指針有指向某個具體的結點
            if (node.random != null) {
                // 串接node被複制結點的隨機指針
                node.next.random = node.random.next;
            }

            // 指向下一個被複制的結點
            node = node.next.next;
        }
    }

    /**
     * 將鏈表拆分,還原原來的鏈表,而且組裝拷貝的鏈表
     *
     * @param head 鏈表頭
     * @return 拷貝的新鏈表頭
     */
    public RandomListNode splitList(RandomListNode head) {
        // 新鏈表頭
        RandomListNode copyHead = head.next;
        // 當前處理的被複制的結點
        RandomListNode node = head;
        // 當前複製的結點
        RandomListNode copy;

        while (node != null){
            // 指向複製結點
            copy = node.next;

            // node.next指向下一個被複制的結點
            node.next = copy.next;

            // 下一個被複制的結點不爲null
            if (node.next != null) {
                // copy.next指向下一個複製的結點
                copy.next = node.next.next;
            }

            // node指向下一個要被處理的被複制結點
            node = node.next;
        }
        return copyHead;
    }
}
相關文章
相關標籤/搜索