如果一个节点能够在它的左右子树中分别找到p和q,则该节点为LCA节点。
在标准的最近公共祖先问题中,我们要在后序位置通过左右子树的搜索结果来判断当前节点是不是LCA:
// 在二叉树中寻找 val1 和 val2 的最近公共祖先节点TreeNode find(TreeNode root, int val1, int val2) {if (root == null) {return null;}// 前序位置if (root.val == val1 || root.val == val2) {// 如果遇到目标值,直接返回return root;}TreeNode left = find(root.left, val1, val2);TreeNode right = find(root.right, val1, val2);// 后序位置,已经知道左右子树是否存在目标值if (left != null && right != null) {// 当前节点是 LCA 节点return root;}return left != null ? left : right;}
但对于 BST 来说,根本不需要老老实实去遍历子树,由于 BST 左小右大的性质,将当前节点的值与val1和val2作对比即可判断当前节点是不是LCA:
假设val1 < val2,那么val1 <= root.val <= val2则说明当前节点就是LCA;若root.val比val1还小,则需要去值更大的右子树寻找LCA;若root.val比val2还大,则需要去值更小的左子树寻找LCA。
// 在 BST 中寻找 val1 和 val2 的最近公共祖先节点TreeNode find(TreeNode root, int val1, int val2) {if (root == null) {return null;}if (root.val > val2) {// 当前节点太大,去左子树找return find(root.left, val1, val2);}if (root.val < val1) {// 当前节点太小,去右子树找return find(root.right, val1, val2);}// val1 <= root.val <= val2// 则当前节点就是最近公共祖先return root;}
