演算法小抄學習筆記 — 7.二叉樹的最近公共祖先
阿新 • • 發佈:2021-01-17
技術標籤:labuladong演算法小抄筆記leetcode二叉樹
1 二叉樹遞迴靈魂三問
- 這個函式應該幹什麼?
- 函式功能
- 正向邏輯推理
- base case是啥?
- 得到遞迴結果後,會做什麼?
- 反向邏輯推理
下面使用一個題目來示例一下。
2 題目
2.1 236. 二叉樹的最近公共祖先
2.1.1 題目
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
例如,給定如下二叉樹: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
輸出: 3
解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。
示例 2:
輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
輸出: 5
解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。
2.1.2 思路
由於是一個二叉樹的題目,直接寫上二叉樹框架應該沒有問題。
class Solution {
public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) {
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
}
}
下面開始靈魂三問:
2.1.2.1 這個函式應該幹什麼?
函式功能:找出以根節點root
的樹下節點p
和q
的最近公共祖先節點,並返回公共祖先節點。
根據函式功能進行正向邏輯推理(這裡不要把root
認為是最大範圍的根節點):
- 若
p
和q
都在root
root
下p
和q
的最近公共祖先節點。 - 若
p
和q
都不在root
下,返回null
。 - 若
p
和q
只有一個在root
下,返回root
。
2.1.2.2 base case是啥?
root == null
時,返回null
。p == root || q == root
時,返回root
。
2.1.2.3 得到遞迴結果後,會做什麼?
根據遞迴結果進行反向邏輯推理(這裡把root
認為是最大範圍的根節點,不要陷入遞迴)
left
和right
均不為空,則root
為最近公共祖先節點。left
和right
均為空,則沒有最近公共祖先節點。left != null && right == null
,返回left
。相反的情況,返回right
。
然後就不要想這麼多了,先把程式碼寫上吧!如果出錯,肯定是三個問題哪裡沒有答好,就要回去再仔細思考一下,看看有沒有漏,記住回去想的時候最好避免陷入遞迴裡面去想。
2.1.3 程式碼
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
}
if (left == null && right == null) {
return null;
}
return left != null ? left : right;
}
}