Given two nodes of a binary tree p and q, return their lowest common ancestor (LCA).
Each node will have a reference to its parent node. The definition for Node is below:
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
}
According to the definition of LCA on Wikipedia: "The lowest common ancestor of two nodes p and q in a 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)."
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 since a node can be a descendant of itself according to the LCA definition.
Example 3:
Input: root = [1,2], p = 1, q = 2
Output: 1
Constraints:
The number of nodes in the tree is in the range [2, 105].
-109 <= Node.val <= 109
All Node.val are unique.
p != q
p and q exist in the tree.
Solutions
Solution 1: Hash Table
We use a hash table $vis$ to record all nodes on the path from node $p$ to the root node. Then we start from node $q$ and traverse towards the root node. If we encounter a node that exists in the hash table $vis$, then this node is the nearest common ancestor of $p$ and $q$, and we can return it directly.
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
1 2 3 4 5 6 7 8 910111213141516171819202122
"""# Definition for a Node.class Node: def __init__(self, val): self.val = val self.left = None self.right = None self.parent = None"""classSolution:deflowestCommonAncestor(self,p:"Node",q:"Node")->"Node":vis=set()node=pwhilenode:vis.add(node)node=node.parentnode=qwhilenodenotinvis:node=node.parentreturnnode
1 2 3 4 5 6 7 8 91011121314151617181920212223
/*// Definition for a Node.class Node { public int val; public Node left; public Node right; public Node parent;};*/classSolution{publicNodelowestCommonAncestor(Nodep,Nodeq){Set<Node>vis=newHashSet<>();for(Nodenode=p;node!=null;node=node.parent){vis.add(node);}for(Nodenode=q;;node=node.parent){if(!vis.add(node)){returnnode;}}}}
1 2 3 4 5 6 7 8 910111213141516171819202122232425
/*// Definition for a Node.class Node {public: int val; Node* left; Node* right; Node* parent;};*/classSolution{public:Node*lowestCommonAncestor(Node*p,Node*q){unordered_set<Node*>vis;for(Node*node=p;node;node=node->parent){vis.insert(node);}for(Node*node=q;;node=node->parent){if(vis.count(node)){returnnode;}}}};
1 2 3 4 5 6 7 8 9101112131415161718192021
/** * Definition for Node. * type Node struct { * Val int * Left *Node * Right *Node * Parent *Node * } */funclowestCommonAncestor(p*Node,q*Node)*Node{vis:=map[*Node]bool{}fornode:=p;node!=nil;node=node.Parent{vis[node]=true}fornode:=q;;node=node.Parent{ifvis[node]{returnnode}}}
We can use two pointers $a$ and $b$ to point to nodes $p$ and $q$ respectively, and then traverse towards the root node. When $a$ and $b$ meet, it is the nearest common ancestor of $p$ and $q$. Otherwise, if pointer $a$ traverses to the root node, then we let it point to node $q$, and do the same for pointer $b$. In this way, when the two pointers meet, it is the nearest common ancestor of $p$ and $q$.
The time complexity is $O(n)$, where $n$ is the number of nodes in the binary tree. The space complexity is $O(1)$.
1 2 3 4 5 6 7 8 9101112131415161718
"""# Definition for a Node.class Node: def __init__(self, val): self.val = val self.left = None self.right = None self.parent = None"""classSolution:deflowestCommonAncestor(self,p:'Node',q:'Node')->'Node':a,b=p,qwhilea!=b:a=a.parentifa.parentelseqb=b.parentifb.parentelsepreturna
1 2 3 4 5 6 7 8 91011121314151617181920
/*// Definition for a Node.class Node { public int val; public Node left; public Node right; public Node parent;};*/classSolution{publicNodelowestCommonAncestor(Nodep,Nodeq){Nodea=p,b=q;while(a!=b){a=a.parent==null?q:a.parent;b=b.parent==null?p:b.parent;}returna;}}
1 2 3 4 5 6 7 8 91011121314151617181920212223
/*// Definition for a Node.class Node {public: int val; Node* left; Node* right; Node* parent;};*/classSolution{public:Node*lowestCommonAncestor(Node*p,Node*q){Node*a=p;Node*b=q;while(a!=b){a=a->parent?a->parent:q;b=b->parent?b->parent:p;}returna;}};
/** * Definition for Node. * type Node struct { * Val int * Left *Node * Right *Node * Parent *Node * } */funclowestCommonAncestor(p*Node,q*Node)*Node{a,b:=p,qfora!=b{ifa.Parent!=nil{a=a.Parent}else{a=q}ifb.Parent!=nil{b=b.Parent}else{b=p}}returna}