題目描述:
給定一個二叉搜索樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義爲:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示爲一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。
我們來看一下二叉搜索樹的特徵:對於一個結點而言,它的左孩子的值一定比它小,右孩子的值一定比它大。
故根據這個特點我們可以將題目整理成三種情況:
- 當給定的p q 結點的 val 都比 root 的值小,則說明應該在根結點的左子樹中找最近公共祖先。(因爲根結點的左孩子結點,不一定是 p q 的最近公共祖先,故仍需向下遍歷)
- 當給定的p q 結點的 val 都比 root 的值大,則說明應該在根結點的右子樹中找最近公共祖先。(右子樹也許向下遍歷)
- 當 p q 結點分在當下根結點的左右兩邊時,即可說明該結點就是最近公共祖先。
代碼如下👇
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//根結點的值
int parentVal = root.val;
//p結點的值
int pVal = p.val;
//q結點的值
int qVal = q.val;
if (pVal > parentVal && qVal > parentVal) {
//pq結點都在根結點的右子樹上,則從根結點的右孩子往下遍歷
return lowestCommonAncestor(root.right, p, q);
} else if (pVal < parentVal && qVal < parentVal) {
//pq結點都在根結點的左子樹上,則從根結點的左孩子往下遍歷
return lowestCommonAncestor(root.left, p, q);
} else {
//如果他們兩個沒在一邊,則說明找到了最近結點值
return root;
}
}
}