给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树T的两个节点p、q,最近公共祖先表示为一个节点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)”。
/**
* 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) {
if(root == null) return null;
if(p == q) return p; // 递归终止条件
if(root == p || root ==q) return root;
List<TreeNode> last_level = new ArrayList<>();
last_level.add(root);
TreeNode p_parent = new TreeNode(0); // p的父节点
TreeNode q_parent = new TreeNode(0); // q的父节点
int count_sum = 0;
while(last_level.size() != 0) {
List<TreeNode> now_level = new ArrayList<>();
int count = 0; // 计算这层有p、q中的几个
TreeNode temp = new TreeNode(0);
for(TreeNode node : last_level) {
TreeNode left = node.left;
TreeNode right = node.right;
if(left != null) now_level.add(left);
if(right != null) now_level.add(right);
if(left == p || right == p) {
temp = left == p ? left : right;
p_parent = node;
count++;
count_sum++;
}
if(left == q || right == q) {
temp = left == q ? left : right;
q_parent = node;
count++;
count_sum++;
}
}
if(count == 1) { // 将p、q上升到同一层
if(count_sum == 2) {
if(p == temp) {
return lowestCommonAncestor(root, p_parent, q);
}
else return lowestCommonAncestor(root, p, q_parent);
}
}
if(count == 2) return lowestCommonAncestor(root, p_parent, q_parent);
last_level = now_level;
}
return null;
}
}
上述代码没有考虑到二叉搜索树的性质(不过这套代码在236也可以行得通),参考大佬的代码,使用二叉搜索树的性质再进行递归就简洁多了
/**
* 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) {
if(p.val > root.val && q.val > root.val){ // 如果都大于root说明在右子树中
return lowestCommonAncestor(root.right,p,q);
} else if(p.val < root.val && q.val < root.val){ // 如果都小于root说明在左子树中
return lowestCommonAncestor(root.left,p,q);
} else {
return root;
}
}
}