ETH官方钱包

前往
大廳
主題

LeetCode - 0987. Vertical Order Traversal of a Binary Tree 解題心得

Not In My Back Yard | 2023-07-23 12:00:10 | 巴幣 0 | 人氣 126

題目連結:


題目意譯:
給定一個二元樹的根節點 root,請算出該二元樹的「垂直探訪」。

對於每個位於位置 (row, col) 的節點,其左子節點以及右子節點的位置分別會在 (row + 1, col - 1) 和 (row + 1, col + 1) 上。該樹的根節點位於 (0, 0) 上。

一個二元樹的「垂直探訪」為一個列表,其中包含著對於每個從最左邊的行開始到最右邊的行為止之行數索引值由上至下之序列。可能存在多個節點在同一列以及同一行,在這個情況下,將這些節點按照它們的數值由小排到大。

回傳給定的二元樹之垂直探訪。

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



範例測資:
範例 1:
輸入: root = [3,9,20,null,null,15,7]
輸出: [[9],[3,15],[20],[7]]
解釋:
行數 -1:只有節點 9 在這一行。
行數 0:節點 3 和 15 在這一行,並且其由上至下之順序為此順。
行數 1:只有節點 20 在這一行。
行數 2:只有節點 7 在這一行。

範例 2:
輸入: root = [1,2,3,4,5,6,7]
輸出: [[4],[2],[1,5,6],[3],[7]]
解釋:
行數 -2:只有節點 4 在這一行。
行數 -1:只有節點 2 在這一行。
行數 0:節點 1 、 5 和 6 在這一行。
        1 在最上面,所以順序是它優先。
        5 和 6 在同一個位置 (2, 0),所以我們根據它們的數值排序,5 先於 6。
行數 1:只有節點 3 在這一行。
行數 2:只有節點 7 在這一行。

範例 3:
輸入: root = [1,2,3,4,6,5,7]
輸出: [[4],[2],[1,5,6],[3],[7]]
解釋:
這個例子跟範例 2 基本一樣,不過節點 5 和 6 交換了。
注意到答案依舊是一樣的,因為 5 和 6 一樣會在同一個位置,並應以數值大小來排序。


解題思維:
這題對 C++ 的話就是可以拿來活用 map 這個容器(Container)的時候了。

不知道要開多少空間來裝行數?沒關係把行數直接當作 map 的鍵值(Key)即可,map 會自動幫你動態分配記憶體。

那每一行裡面要開多少空間來裝列數?把第一層 map 的映射值(value)再套一個 map 上去,並將列數作為這個新定義的第二層 map 之鍵值。

再來,由於可能有多個節點在同一個位置,所以第二層的 map 之映射值還需要是一個動態陣列(例如說 vector)來裝那些節點的數值。

接著只要進行一個深度優先搜尋(Depth First Search,DFS),算出每一個節點的行數與列數並放到 map 中相應位置即可。

最後只要掃過每一行(map 會很好心的把鍵值按照順序排好,預設是由小到大),然後對於每一列,一列一列地把其中的元素排序(如果只有一個沒差,但有多個節點在同一位置就要按照數值排序)。然後把這些資訊塞到一個二維陣列中即可。



如果不用 map 呢?那你需要先自行進行深度優先搜尋一次來找到最左到最右的跨足行數多少,然後同時也要看列數最多到多少。知道行列各自最多到多少便可以開出相對應的大小之二維陣列(一樣,每個位置依舊是一個動態陣列)。接著的程序就與上面差不多了。




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

創作回應

更多創作