LeetCode小結 樹的最優子結構(遞迴)

2021-10-09 13:02:37 字數 1695 閱讀 9381

做了很多樹的題目,發現非常多遞迴求最優子結構的(最大經過節點數、最長路徑等)

大意:

給定乙個二叉樹,找出其最大深度。

二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。

說明: 葉子節點是指沒有子節點的節點。

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...