原题url: 236. Lowest Common Ancestor of a Binary Tree
根据自己的思路写出来的代码性能太差。
网上的解答一:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) return root; // 为null 或者 本身相等
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left != null && right != null) return root;
// p,q,左边存在一个,右边存在一个,说明当前节点正是要返回的祖先节点。
if(left == null) return right;
// 如果左子树中没有 p 和 q, 则返回右子树中求出来的返回节点。
if(right == null) return left;
// 如果右子树中没有 p 和 q, 则返回左子树中求出来的返回节点。
}
}
Solution中的第一个解答:
// mid + left + right >= 2
// 满足上述条件时,说明找到最近的公共祖先节点。
class Solution {
private TreeNode ans;
public Solution() {
// Variable to store LCA node.
this.ans = null;
}
private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
// If reached the end of a branch, return false.
if (currentNode == null) {
return false;
}
// Left Recursion. If left recursion returns true, set left = 1 else 0
int left = this.recurseTree(currentNode.left, p, q) ? 1 : 0;
// Right Recursion
int right = this.recurseTree(currentNode.right, p, q) ? 1 : 0;
// If the current node is one of p or q
int mid = (currentNode == p || currentNode == q) ? 1 : 0;
// If any two of the flags left, right or mid become True
if (mid + left + right >= 2) {
this.ans = currentNode;
}
// Return true if any one of the three bool values is True.
return (mid + left + right > 0);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// Traverse the tree
this.recurseTree(root, p, q);
return this.ans;
}
}
观察代码中给 返回节点 ans 赋值的语句。 只有当 mid + left + right > 2 时 将当前节点赋值给要返回的节点 ans。
考虑以下三种情况。
mid = 1, left = 1;
mid = 1, right = 1;
// 上面: 当前节点 等于 p 或 q,剩下的 p 或 q 在 左/右 子树中。
left = 1, right = 1;
// p,q 在当前节点的左右子树中各有一个。