前往
大廳
主題

LeetCode - 116. Populating Next Right Pointers in Each Node 解題心得

Not In My Back Yard | 2022-08-19 12:00:17 | 巴幣 0 | 人氣 181

題目連結:


題目意譯:
你被給定一個完美二元樹,其中所有葉節點都位於同一階層上且每個父母節點都有著兩個小孩。該二元樹有著以下定義:
struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

將每個指標 next 都填上其所屬節點右側的「下一個」節點。如果右側的下一個節點不存在,則指標 next 應設為 NULL。

一開始,所有指標 next 都被設成 NULL。

限制:
樹中的節點數位於範圍 [0, 2 ^ 12 - 1] 中。
-1000 ≦ Node.val ≦ 1000

進階:
你只能使用常數額外空間。
遞迴的方式是可被接受的。你可以假設在本題中隱含的堆疊空間不算作額外空間。



範例測資:
範例 1:
輸入: root = [1,2,3,4,5,6,7]
輸出: [1,#,2,3,#,4,5,6,7,#]
解釋: 給定上圖的完美二元樹(圖 A),你的函式應將每個指標 next 都指向其右側的下一個節點,如圖 B 所示。序列化的輸出為階層探訪(Level order),其中每一層是由指標 next 們連接在一起,而 '#' 則用來標示每一層的結尾。

範例 2:
輸入: root = []
輸出: []


解題思維:
首先,直接做一次階層探訪(Level-order Traversal,如這題),然後把每一層中的節點指向位於其右側的節點的這個方法當然可行。只是不符合進階的 O(1)(即常數)空間需求。



因此接著我們來觀察下圖
可以看到由於給定的樹是完美二元樹,因此可以看到紅色圈圈節點的左小孩(橘色圈圈)的 next 會指向它的右小孩(紫色圈圈)。

那紫色圈圈的 next 呢?可以看到位於它右側的實際上就是紅色圈圈的節點之 next ,其所指向的節點之左小孩。

根據以上我們就可以寫出非常簡潔的遞迴函式:
Connect(*nowNode, *sibling)
  if nowNode == NULL
    return
  nowNode->next = sibling
  Connect(nowNode->left, nowNode->right)
  if sibling != NULL
    Connect(nowNode->right, sibling->left)
  else
    Connect(nowNode->right, NULL)
其中 nowNode 代表著當前的節點,而 sibling 即代表著 nowNode 的父母節點 next 之指向。然後我們只需要呼叫 Connect(root, NULL) 便可以完成遞迴地完成所有紅色箭頭(next)。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作