輸入為一個二元樹,以陣列回傳從最左到最右的樹枝總和。
二元樹是每個節點最多只有兩個分支的樹結構,樹枝 (branch) 指的是從根節點到任意葉節點的路徑,樹枝總和是指路徑上所有節點值的總和。
如下結構,每一個 BinaryTree
節點有一個整數值 value
,左子節點 left
,右子節點 right
。子節點可能為其他 BinaryTree
節點或為空值。
class BinaryTree {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
sample input:
tree = 1
/ \
2 3
/ \ / \
4 5 6 7
/ \ /
8 9 10
sample output:
[15, 16, 18, 10, 11]
// 15 == 1 + 2 + 4 + 8
// 16 == 1 + 2 + 4 + 9
// 18 == 1 + 2 + 5 + 10
// 10 == 1 + 3 + 6
// 11 == 1 + 3 + 7
這題要計算從左到右的樹枝和,方法是以深度優先搜尋的方式遍歷二元樹,對每個子節點呼叫遞迴式,並傳入累計的總和進行計算。當碰到葉節點,也就是節點沒有子節點時,將該分支的總和加入結果陣列中。
若 n 代表二元樹中的節點數量,
time: O(n) 因為需要遍歷每個節點來計算總合。
space: O(n) 空間來自堆疊以及結果陣列,以下分開討論。
堆疊:以結構平衡的二元樹來說,樹的高度為 log(n),所以從根節點到葉節點需要 log(n) 堆疊空間。但若是最糟狀況,也就是所有的節點都集中在同一側,則需要 n 堆疊空間。
結果陣列:陣列長度相當於樹枝的數量,也就是樹中葉節點的數量。葉節點數一定會小於 n,而在平衡的二元樹中,葉節點數可以大致表達為 n / 2,所以空間為 n。
function branchSums(node, sum = 0, results = []) {
if (!node) return;
sum += node.value;
if (!node.left && !node.right) {
results.push(sum);
return results;
}
branchSums(node.left, sum, results);
branchSums(node.right, sum, results);
return results;
}