[路飞]_每天刷leetcode_37(二叉搜索树的最近公共祖先 Lowest Common Ancestor of a Binary Search Tree)

403 阅读2分钟

二叉搜索树的最近公共祖先(Lowest Common Ancestor of a Binary Search Tree)

LeetCode传送门235. Lowest Common Ancestor of a Binary Search Tree

题目

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

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:

binarysearchtree_improved.png

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.

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.

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

Constraints:

  • The number of nodes in the tree is in the range [2,105][2, 10^5].
  • 109<=Node.val<=109-10^9 <= Node.val <= 10^9
  • All Node.val are unique.
  • p != q
  • p and q will exist in the BST.

思考线


解题思路

这道题的关键是这棵二叉树是二叉搜索树,我们可以根据二叉搜索树的特点来做这道题。

我们 从根节点来遍历

  1. 如果 testNode > q && testNode > p, 说明 p & q 都在左子节点。 我们将testNode = testNode.left 然后继续遍历。
  2. 如果 testNode < q && testNode < p, 说明 p & q 都在右子节点。 我们将testNode = testNode.right 然后继续遍历。
  3. 如果不是1和2 中的情况,则说明 要么这个节点是p 和 q 的分叉点,要么,这个节点就是p和q 其中一个元素。总之,这个就是我们要找的最近的公共祖先节点。

根据以上思路完成代码如下。

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null {
    // 根据二叉搜索树的特点来做这道题,
    // 我们从根节点来遍历,如果testNode > p && root > q ,说明 q和p都在左节点。
    // 我们将testNode 赋值给testNode.left 继续遍历
    // 若 testNode < p && testNode < q, 说明p和q都在右节点上
    // 其余情况说明要么是分叉点要么是其中某一个元素。总之,我们找到了最近的公共祖先节点
    let testNode = root;
    while(testNode) {
        if(testNode.val > q.val && testNode.val > p.val) {
            testNode = testNode.left
        } else if(testNode.val < q.val && testNode.val < p.val) {
            testNode = testNode.right
        } else {
            return testNode;
        }
    }
    return null;
};

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。