package com.freetymekiyan.algorithms.level.easy;
import com.freetymekiyan.algorithms.utils.Utils.TreeNode;
/**
* Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
* <p>
* 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).”
* |
* | _______6______
* | / \
* | ___2__ ___8__
* | / \ / \
* | 0 _4 7 9
* | / \
* | 3 5
* |
* For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6.
* <p>
* Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA
* definition.
* <p>
* Company Tags: Amazon, Microsoft, Facebook, Twitter
* Tags: Tree
* Similar Problems: (M) Lowest Common Ancestor of a Binary Tree
*/
public class LowestCommonAncestorOfBST {
/**
* Iterative.
* In BST, the lca's value can only be [p, q].
* And lca is the first from top to bottom that lies in range.
* If the value is less than both p and q's values, move to right subtree.
* If the value is more than both p and q's values, move to left subtree.
* Otherwise, we found the node.
*/
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (root != null) {
if (root.val < p.val && root.val < q.val) {
root = root.right;
} else if (root.val > p.val && root.val > q.val) {
root = root.left;
} else {
return root;
}
}
return null; // Reach null and lca not found.
}
/**
* Recursion.
* LCA's value must be between [p, q].
* Statement:
* Given root, p, q, find the LCA of p and q.
* Recurrent relation:
* If root's value < p's and q's, LCA is in the right subtree.
* If root's value > p's and q's, LCA is in the left subtree.
* Else, root's value in between, LCA is root.
* Base case:
* If root is null, return null.
* Complete task:
* Deal with base case. Search left, search right. Return result.
*/
public TreeNode lowestCommonAncestorB(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestorB(root.right, p, q);
} else if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestorB(root.left, p, q);
}
return root;
}
}