Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5
and 1
is 3
. Another example is LCA of nodes 5
and 4
is 5
, since a node can be a descendant of itself according to the LCA definition.
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null){
return null;
}
if(root == p || root == q){
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left != null && right != null){
return root;
}
if(left != null){
return left;
}else{
return right;
}
}
}
// To find LCA of nodes n1 and n2 in Binary Tree
Node LCA(Node n1, Node n2)
{
// Creata a map to store ancestors of n1
Map<Node, Boolean> ancestors = new HashMap<Node, Boolean>();
// Insert n1 and all its ancestors in map
while (n1 != null)
{
ancestors.put(n2, Boolean.TRUE);
n1 = n1.parent;
}
// Check if n2 or any of its ancestors is in
// map.
while (n2 != null)
{
if (ancestors.containsKey(n2) != ancestors.isEmpty())
return n2;
n2 = n2.parent;
}
return null;
}
Node lca(Node node, int n1, int n2)
{
if (node == null)
return null;
// If both n1 and n2 are smaller than root, then LCA lies in left
if (node.data > n1 && node.data > n2)
return lca(node.left, n1, n2);
// If both n1 and n2 are greater than root, then LCA lies in right
if (node.data < n1 && node.data < n2)
return lca(node.right, n1, n2);
return node;
}
指向parent的指针的做法,不用额外空间的是这样的:
1. 得到2个链条的长度。
2.将长的链条向前移动差值(len1 - len2)
3.两个指针一起前进,遇到相同的即是交点,如果没找到,返回null.
public ListNode getIntersectionNode1(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
int lenA = getLen(headA);
int lenB = getLen(headB);
if (lenA > lenB) {
while (lenA > lenB) {
headA = headA.next;
lenA--;
}
} else {
while (lenA < lenB) {
headB = headB.next;
lenB--;
}
}
while (headA != null) {
if (headA == headB) {
return headA;
}
headA = headA.next;
headB = headB.next;
}
return null;
}
public int getLen(ListNode node) {
int len = 0;
while (node != null) {
len++;
node = node.next;
}
return len;
}