二叉搜索树的最近公共祖先(Lowest Common Ancestor of a Binary Search Tree)
LeetCode传送门235. Lowest Common Ancestor of a Binary Search Tree
题目
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Example:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
Input: root = [2,1], p = 2, q = 1
Output: 2
Constraints:
- The number of nodes in the tree is in the range .
- All Node.val are unique.
- p != q
- p and q will exist in the BST.
思考线
解题思路
这道题的关键是这棵二叉树是二叉搜索树,我们可以根据二叉搜索树的特点来做这道题。
我们 从根节点来遍历
- 如果
testNode > q && testNode > p, 说明p & q都在左子节点。 我们将testNode = testNode.left然后继续遍历。 - 如果
testNode < q && testNode < p, 说明p & q都在右子节点。 我们将testNode = testNode.right然后继续遍历。 - 如果不是
1和2中的情况,则说明 要么这个节点是p 和 q的分叉点,要么,这个节点就是p和q其中一个元素。总之,这个就是我们要找的最近的公共祖先节点。
根据以上思路完成代码如下。
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null {
// 根据二叉搜索树的特点来做这道题,
// 我们从根节点来遍历,如果testNode > p && root > q ,说明 q和p都在左节点。
// 我们将testNode 赋值给testNode.left 继续遍历
// 若 testNode < p && testNode < q, 说明p和q都在右节点上
// 其余情况说明要么是分叉点要么是其中某一个元素。总之,我们找到了最近的公共祖先节点
let testNode = root;
while(testNode) {
if(testNode.val > q.val && testNode.val > p.val) {
testNode = testNode.left
} else if(testNode.val < q.val && testNode.val < p.val) {
testNode = testNode.right
} else {
return testNode;
}
}
return null;
};
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。