Given the root
of a binary tree, return the lowest common ancestor (LCA) of two given nodes, p
and q
. If either node p
or q
does not exist in the tree, return null
. All values of the nodes in the tree are unique.
According to the definition of LCA on Wikipedia: "The lowest common ancestor of two nodes p
and q
in a binary tree T
is the lowest node that has both p
and q
as descendants (where we allow a node to be a descendant of itself)". A descendant of a node x
is a node y
that is on the path from node x
to some leaf node.
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5. A node can be a descendant of itself according to the definition of LCA.
Example 3:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 10 Output: null Explanation: Node 10 does not exist in the tree, so return null.
Constraints:
- The number of nodes in the tree is in the range
[1, 104]
. -109 <= Node.val <= 109
- All
Node.val
are unique. p != q
Follow up: Can you find the LCA traversing the tree, without checking nodes existence?
Companies:
Facebook, Microsoft
Related Topics:
Tree, Depth-First Search, Binary Tree
Similar Questions:
- Lowest Common Ancestor of a Binary Search Tree (Easy)
- Lowest Common Ancestor of a Binary Tree (Medium)
- Lowest Common Ancestor of a Binary Tree III (Medium)
- Lowest Common Ancestor of a Binary Tree IV (Medium)
// OJ: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-ii/
// Author: github.com/lzl124631x
// Time: O(N)
// Space: O(H)
class Solution {
bool findPath(TreeNode *node, TreeNode *target, vector<TreeNode*> &path) {
if (!node) return false;
path.push_back(node);
if (node == target) return true;
if (findPath(node->left, target, path) || findPath(node->right, target, path)) return true;
path.pop_back();
return false;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> a, b;
findPath(root, p, a);
findPath(root, q, b);
TreeNode *ans = nullptr;
for (int i = 0; i < a.size() && i < b.size() && a[i] == b[i]; ++i) ans = a[i];
return ans;
}
};
// OJ: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-ii/
// Author: github.com/lzl124631x
// Time: O(N)
// Space: O(H)
class Solution {
TreeNode *ans = nullptr;
int dfs(TreeNode *root, TreeNode *p, TreeNode *q) { // returns the number of matched nodes in this subtree
if (!root || ans) return 0; // if we've already found the LCA, we can skip all subsequent DFS.
int left = dfs(root->left, p, q), right = dfs(root->right, p, q), cnt = left + right + (root == p || root == q);
if (cnt == 2 && (left == 1 || right == 1)) ans = root; // If this subtree has two matched nodes and either the left or right subtree only has exactly one matched node, this is the LCA.
return cnt;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
dfs(root, p, q);
return ans;
}
};
// OJ: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-ii/
// Author: github.com/lzl124631x
// Time: O(N)
// Space: O(H)
class Solution {
int cnt = 0;
TreeNode* dfs(TreeNode *root, TreeNode *p, TreeNode *q) {
if (!root) return nullptr;
auto left = dfs(root->left, p, q), right = dfs(root->right, p, q);
if (root == p || root == q) {
++cnt;
return root;
}
return left && right ? root : (left ? left : right);
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
auto ans = dfs(root, p, q);
return cnt == 2 ? ans : nullptr;
}
};