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;
    }

}

@@ -106,16 +106,78 @@
 e;%0A%0A/**%0A
+ * 235. Lowest Common Ancestor of a Binary Search Tree%0A * %3Cp%3E%0A
  * Given
@@ -274,16 +274,16 @@
 he BST.%0A
-
  * %3Cp%3E%0A 
@@ -1432,36 +1432,99 @@
   * 
-Otherwise, we found the node
+If the value is in between the two nodes, return the node.%0A     * Otherwise there is no LCA
 .%0A  
@@ -2038,76 +2038,8 @@
 q%5D.%0A
-     * Statement:%0A     * Given root, p, q, find the LCA of p and q.%0A
     
@@ -2810,14 +2810,48 @@
 oot;
+ // root's value in between p and q.
 %0A    %7D%0A
-%0A%7D%0A
+%7D

update 235. Lowest Common Ancestor of a Binary Search Tree