做了很多樹的題目,發現非常多遞迴求最優子結構的(最大經過節點數、最長路徑等)
大意:
給定乙個二叉樹,找出其最大深度。
二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。
說明: 葉子節點是指沒有子節點的節點。
class
solution
};
變型題:
543. 二叉樹的直徑
大意:
給定一棵二叉樹,你需要計算它的直徑長度。一棵二叉樹的直徑長度是任意兩個結點路徑長度中的最大值。這條路徑可能穿過也可能不穿過根結點。
題解:由於最長路徑其實就是求最大節點。某條路經過的最大節點數量減一,就是最長路徑了。所以只要求某節點的左子樹的最大高度,加上右子樹的最大高度,再加上1(節點自己),就是從右子樹某節點開始,到左子樹某節點終結的最優解。然後一路遞迴上去,直到根節點,就是最終的最優解。
(詳解去看官方解答)
class
solution
intdiameterofbinarytree
(treenode* root)
};
邏輯相同,但細節更複雜一些:
我們使用爺爺、兩個孩子、4 個孫子來說明問題
首先來定義這個問題的狀態
爺爺節點獲取到最大的偷取的錢數呢
首先要明確相鄰的節點不能偷,也就是爺爺選擇偷,兒子就不能偷了,但是孫子可以偷
二叉樹只有左右兩個孩子,乙個爺爺最多 2 個兒子,4 個孫子
根據以上條件,我們可以得出單個節點的錢:
4 個孫子偷的錢 + 爺爺的錢 vs 兩個兒子偷的錢 哪個組合錢多,就當做當前節點能偷的最大錢數。這就是動態規劃裡面的最優子結構。由於是二叉樹,這裡可以選擇計算所有子節點(讓所有節點都做一次爺爺)
遞迴到最後相當於是從底層算到高層,最後算到root就是最後結果了。每次返回的result相當於是子樹的最優解,這樣就包含了所有可能的情況。(包括乙個右兒子和兩個左孫子的情況)。每次算出的最優解都儲存在了hash表中,用節點的位址值和該節點的子樹最優取值相繫結。這樣多次計算的時候就不用再進行重複的遞迴計算了。
class
solution
if(root-
>right)
int result =
max(yesun,
rob(root-
>left)
+rob
(root-
>right));
m[root]
= result;
return result;}}
;
思路和我的差不多,還是不知道什麼時候該返回,什麼時候用void。我的思路是543和104改的。利用葉子節點左右兒子樹返回兩個0來計算最優子結構。同時記錄上乙個返回上來的last。
但理解題解,發現傳入引數才是更好的做法。dir引數是父節點給子節點的方向路徑。dis是當前距離。每次遞迴進一層時判斷一次最大。然後根據dir來選擇不同的遞迴方式。
(利用返回值時自底向上,利用正向遞迴時自頂向下)
class
solution
else
}int
longestzigzag
(treenode* root)
};
Leetcode 樹的子結構
leetcode 輸入兩棵二叉樹a和b,判斷b是不是a的子結構。約定空樹不是任意乙個樹的子結構 b是a的子結構,即 a中有出現和b相同的結構和節點值。思路 先判斷b 為空,則返回 false 在a中遍歷,看b的根節點是否出現 如果出現,比較這個節點的子樹是否與b 相同 definition for ...
leetcode 樹的子結構
輸入兩棵二叉樹a和b,判斷b是不是a的子結構。約定空樹不是任意乙個樹的子結構 b是a的子結構,即 a中有出現和b相同的結構和節點值。例如 給定的樹 a 3 4 5 1 2給定的樹 b 4 1返回 true,因為 b 與 a 的乙個子樹擁有相同的結構和節點值。由於當前子結構的根節點可能位於樹中任意節點...
《LeetCode筆記51》 樹的子結構
輸入兩棵二叉樹a和b,判斷b是不是a的子結構。約定空樹不是任意乙個樹的子結構 b是a的子結構,即 a中有出現和b相同的結構和節點值。例如 給定的樹 a 3 4 5 1 2 給定的樹 b 4 1 返回 true,因為 b 與 a 的乙個子樹擁有相同的結構和節點值。示例 1 輸入 a 1,2,3 b 3...