LeetCode Notes_#430_扁平化多級雙向連結串列
阿新 • • 發佈:2020-08-28
LeetCode Notes_#430_扁平化多級雙向連結串列
LeetCodeContents
題目
多級雙向連結串列中,除了指向下一個節點和前一個節點指標之外,它還有一個子連結串列指標,可能指向單獨的雙向連結串列。這些子列表也可能會有一個或多個自己的子項,依此類推,生成多級資料結構,如下面的示例所示。
給你位於列表第一級的頭節點,請你扁平化列表,使所有結點出現在單級雙鏈表中。
示例 1:
輸入:head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
輸出:[1,2,3,7,8,11,12,9,10,4,5,6]
解釋:
輸入的多級列表如下圖所示:
扁平化後的連結串列如下圖:
提示:
- 節點數目不超過 1000
- 1 <= Node.val <= 10^5
思路
我們將列表順時針轉 90 °,那麼就會看到一顆二叉樹,則扁平化的操作也就是對二叉樹進行先序遍歷(深度優先搜尋)。更準確的說,除了按照先序遍歷的順序訪問,還需要注意的還需要按對節點進行雙向連線。
在圖中,我們將child
看作二叉樹的left
指標,將next
指標看作二叉樹中的right
指標。
遞迴函式Node flattenDFS(Node prev, Node cur)
兩個引數就是扁平化後的雙向連結串列的相鄰兩個節點。
返回值是tail
終止條件
cur == null
,說明它的前一個節點prev
就已經是最左下角的那個節點(即tail
),直接返回prev
。
遞推過程
prev
與next
之間建立雙向連線- 暫存
cur.next
節點到變數tmpNext
中,因為cur.next
在遞迴呼叫過程中會發生改變 - 遞迴呼叫
Node tail = flattenDFS(cur, cur.child);
,將連結串列看成是二叉樹的話,相當於遞迴訪問左子樹的過程。- 將每對具有父子關係的節點建立雙向連線。
- 返回
tail
節點,即當前已經做完扁平化處理的連結串列的最後一個節點,這個節點要連線到tmpNext
- 刪除
cur.child
指標,原因是cur
/cur_child
之間已經建立了雙向連線,child
指標就不需要了。 - 遞迴呼叫並返回值
return flattenDFS(tail, tmpNext);
,將連結串列看成是二叉樹的話,相當於遞迴訪問右子樹的過程。- 左子樹的最後一個節點是剛才記下的
tail
,將其連線到右子樹的第一個節點tmpNext
。 - 返回值是
tmpNext
的最左下角節點。
- 左子樹的最後一個節點是剛才記下的
解答
class Solution {
public Node flatten(Node head) {
if(head == null) return head;
//因為head沒有prev指標,所以新增一個dummyHead,dummyHead.next = head,那麼可以直接呼叫遞迴函式處理
Node dummyHead = new Node(0, null, head, null);
flattenDFS(dummyHead, head);
//斷開head.prev指標
dummyHead.next.prev = null;
return dummyHead.next;
}
//這裡的prev/cur指的是在扁平列表中,需要建立雙向連線的兩個相鄰節點,可能是父子關係,也可能本來就是相鄰關係
//分為cur有孩子,沒孩子兩種情況
private Node flattenDFS(Node prev, Node cur){
if(cur == null) return prev;
cur.prev = prev;
prev.next = cur;
//cur.next可能會改變,所以要提前儲存
Node tmpNext = cur.next;
//將child看作左子樹,在cur和cur.child之間建立雙向連線
//tail的意思是,如果cur.child還有左孩子,那麼會不斷遞迴,直到最小的左孩子,記作tail
//有孩子的情況下,tail是最小的孩子,沒孩子的情況下,tail就是cur本身
Node tail = flattenDFS(cur, cur.child);
//已經建立了雙向連線後,就不需要child指標了,將它斷開
cur.child = null;
//有孩子的情況下,將最小的左孩子遍歷完之後,之後連線第一個右孩子
return flattenDFS(tail, tmpNext);
}
}
複雜度分析
時間複雜度:O(n),n是節點個數。
空間複雜度:O(n),遞迴呼叫層數是n,則佔用棧空間是O(n)。