zoukankan      html  css  js  c++  java
  • 二叉搜索树中两个节点的最近公共祖先节点

    标题读起来稍微有点小绕,这是我在力扣上今天碰到的一道题,需要用程序找出二叉搜索树中两个指定节点的最近公共祖先节点。

    最近可以理解为从上往下看最早出现,公共祖先节点就不用多说了,详细题目如下:

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

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

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

     

    示例 1:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
    输出: 6
    解释: 节点 2 和节点 8 的最近公共祖先是 6。

    示例 2:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
    输出: 2
    解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    开始刚一读题也是有点迷,主要原因是不知道什么是二叉搜索树,查了一下,发现在二叉搜索树中,每一个节点的左子树上的节点全部小于它本身节点,右子树上节点正好相反。

    第一直觉是既然给出的是二叉搜索树,那解法应该可以利用它的特性,由于是树状结构,果断想到了递归。

    从根节点开始递归,如果它大于两个节点,或小于两个节点,那就说明,两个节点位于它的同一个子树上,这种情况下,由于是二叉树,它本身肯定不是最近祖先节点(二叉树最多只有两个子节点,如果两节点位于同一子树,那么至少是在当前节点的下下层,这样看来,当前节点的其中一个子节点会更近)。

    如果根节点大于其中一个节点而且小于另一个节点,就说明一个节点位于根节点的左子树,另一个位于右子树。

    那么它是不是最近祖先节点呢?假设它不是,首先由于是二叉树结构,位于树中的两个节点必然有一个最近祖先节点。如果它不是那么必然在它之下,就说明在根节点的左子树或右子树上存在一个两节点的祖先节点,这样的话,两节点必须位于根节点的同一子树上,那就和之前的已有条件冲突了,所以说明这是不可能发生的情况,反向推理,我们已经证明了这种情况下根节点不会不是两节点的最近祖先节点,那么它就必然是两节点的最近祖先节点。

    还有一种特殊情况,两节点的最近祖先节点是两节点其中之一,那么两节点必然位于的层级不同,通过递归寻找节点的途中,必然会先找到他们的最近祖先节点(位于较高层级的那个)。

    最终代码如下(其实还可以优化,当前节点大于两节点或小于两节点的时候,只需要递归它的一个子树即可):

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    
    class Solution {
        TreeNode node = null;
    
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            findCommonNode(root, p, q);
            return node;
        }
    
        public void findCommonNode(TreeNode root, TreeNode p, TreeNode q) {
            if (root == null)
                return;
            if (root.val == p.val || root.val == q.val) {
                node = root;
                return;
            }
            if ((root.val > p.val && root.val < q.val) || (root.val < p.val && root.val > q.val)) {
                node = root;
                return;
            }
            findCommonNode(root.left, p, q);
            findCommonNode(root.right, p, q);
        }
    }
  • 相关阅读:
    C#终止线程的方法
    Socket编程(TCP、UDP)
    频率域滤波基础之五(读数字图像处理学习halcon)
    hihoCoder #1127:二分图最小点覆盖和最大独立集
    hihoCoder #1033 : 交错和 (数位Dp)
    HDU-5536 Chip Factory (字典树)
    hihoCoder #1040 (判断是否为矩形)
    hihoCoder:#1079(线段树+离散化)
    HDU-5532 Almost Sorted Array (LIS)
    UVALive-7303 Aquarium (最小生成树)
  • 原文地址:https://www.cnblogs.com/wxdmw/p/14051929.html
Copyright © 2011-2022 走看看