https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/

この問題の回答方法としては Recursive と Iterative なアプローチがある。

Recursive Approach

アルゴリズム

  1. ルートの Node から始める。
  2. p と q が右の subtree にある場合、1から右のsubtreeを探すようにする。
  3. p と q が左の subtree にある場合、1から左のsubtreeを探すようにする。
  4. もし 2 と 3 のステップが not true の場合、p と q の共通の Node を見つけたこととなる。

Time complexity: O(n)
Mem complexity: O(n)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        parent_val = root.val

        p_val = p.val
        q_val = q.val

        if p_val > parent_val and q_val > parent_val:
            return self.lowestCommonAncestor(root.right, p, q)
        elif p_val < parent_val and q_val < parent_val:
            return self.lowestCommonAncestor(root.left, p, q)
        else:
            return root

Iterative Approach

アルゴリズム

やり方としては Recursive なアプローチと似ている。 違いとしては、recursive な function を呼ぶ代わりに、tree を 横断する。
そのため、backtrace して、LCA node を探す必要がないため stack,recursion を使わない。 Iterative なやり方としては、分かれるポイントを探すこと。

Time complexity: O(n)
Mem complexity: O(1)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        cur = root

        while cur:
            if p.val > cur.val and q.val > cur.val:
                cur = cur.right
            elif p.val < cur.val and q.val < cur.val:
                cur = cur.left
            else:
                return cur