[算法] - 複製含有隨機指針節點的鏈表【 額外空間複雜度O(1)】

複製含有隨機指針節點的鏈表
【 題目】 一種特殊的單鏈表節點類描述如下

class Node {
  int value;
  Node next;
  Node rand;
  Node(int val) {
  value = val;}}

rand指針是單鏈表節點結構中新增的指針, rand可能指向鏈表中的任意一個節點, 也可能指向null。 給定一個由Node節點類型組成的無環單鏈表的頭節點head, 請實現一個函數完成這個鏈表的複製, 並返回複製的新鏈表的頭節點。
【 要求】 時間複雜度O(N), 額外空間複雜度O(1)

不考慮空間複雜度

我們就利用哈希表,其實就是一個普通字典map

首先遍歷一遍,存好map。然後找1的next指針發現是2,然後把2的map對應的2‘給1’的next

	public static class Node {
		public int value;
		public Node next;
		public Node rand;

		public Node(int data) {
			this.value = data;
		}
	}

	public static Node copyListWithRand1(Node head) {
		HashMap<Node, Node> map = new HashMap<Node, Node>();
		Node cur = head;
		while (cur != null) {
			map.put(cur, new Node(cur.value));//克隆節點給mapnew Node(cur.value)
			cur = cur.next;
		}
		cur = head;
		while (cur != null) {
			map.get(cur).next = map.get(cur.next);//新節點的當前的next = 原先的next指向的克隆map節點
			map.get(cur).rand = map.get(cur.rand);
			cur = cur.next;
		}
		return map.get(head);//返回頭結點的克隆節點
	}

考慮空間複雜度:不用map

利用結構的設計,將map替代

成對設計

成對兒取出,

這樣的設計,新節點的next指針就是下下一個node(注意邊界),新節點的rand指針就是上一個節點的rand指針的next的node。

1‘的next指針很好找,rand指針,因爲1的rand指針是3,所以1’克隆指針就是3的next。

	public static Node copyListWithRand2(Node head) {
		if (head == null) {
			return null;
		}
        // 成對設計
		Node cur = head;//當前 節點 初始化  到頭結點 
		Node next = null;
		// copy node and link to every node
		// 1_>2
		// 1_>1'_>2
		while (cur != null) {
			next = cur.next;//記錄後面的環境 2
			cur.next = new Node(cur.value);//當前節點的下一個就是克隆的節點
			cur.next.next = next;//當前節點的下下一個,是原先的next 2
			cur = next;//走向下一個節點 2
		}
		cur = head;
		Node curCopy = null;//curCopy就是新節點
		// set copy node rand
		// 1——1'——2-2’
		// 成對取出
		while (cur != null) {
			next = cur.next.next;//記錄的下一次的開始的位置,因爲成對取出,所以是後後的環境 2,
			curCopy = cur.next;//拷貝的數據本身data是1'
			curCopy.rand = cur.rand != null ? cur.rand.next : null;
			cur = next;
		}
		Node res = head.next;
		cur = head;
		// split 老鏈表鏈接好,新聯表連接好 重新鏈接next指針
		while (cur != null) {
			next = cur.next.next;//成對遍歷
            
			curCopy = cur.next;
			cur.next = next;
			curCopy.next = next != null ? next.next : null;
            
			cur = next;
		}
		return res;

 

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