LeetCode 235. Lowest Common Ancestor of a Binary Search Tree(二叉搜索树的最小共同父节点)

322 阅读1分钟

leetcode.com/problems/lo…

Discuss: www.cnblogs.com/grandyang/p…

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

 

Example 1:

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.

Example 2:

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [2,1], p = 2, q = 1
Output: 2

 

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 will exist in the BST.

解法一:

这道题我们可以用递归来求解,我们首先来看题目中给的例子,由于二叉搜索树的特点是左<根<右,所以根节点的值一直都是中间值,大于左子树的所有节点值,小于右子树的所有节点值,那么我们可以做如下的判断,如果根节点的值大于p和q之间的较大值,说明p和q都在左子树中,那么此时我们就进入根节点的左子节点继续递归,如果根节点小于p和q之间的较小值,说明p和q都在右子树中,那么此时我们就进入根节点的右子节点继续递归,如果都不是,则说明当前根节点就是最小共同父节点,直接返回即可,参见代码如下:

class Solution {
    fun lowestCommonAncestor(root: TreeNode?, p: TreeNode?, q: TreeNode?): TreeNode? {
        if (root == null) {
            return null
        }

        return when {
            root.`val` > p!!.`val`.coerceAtLeast(q!!.`val`) -> {
                lowestCommonAncestor(root.left, p, q)
            }
            root.`val` < p.`val`.coerceAtMost(q.`val`) -> {
                lowestCommonAncestor(root.right, p, q)
            }
            else -> {
                root
            }
        }
    }
}

解法二:

当然,此题也有非递归的写法,用个 while 循环来代替递归调用即可,然后不停的更新当前的根节点,也能实现同样的效果,代码如下:

class Solution {
    fun lowestCommonAncestor(root: TreeNode?, p: TreeNode?, q: TreeNode?): TreeNode? {
        var tempNode = root
        while (true) {
            tempNode = if (tempNode!!.`val` > p!!.`val`.coerceAtLeast(q!!.`val`)) {
                tempNode.left
            } else if (tempNode.`val` < p.`val`.coerceAtMost(q.`val`)) {
                tempNode.right
            } else {
                break
            }
        }
        return tempNode
    }
}