算法 - 求二叉搜索树的最近公共祖先

算法 - 求二叉搜索树的最近公共祖先

1. 案例

给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先(一个节点也可以是它自己的祖先)。所有节点的值都是唯一的。

p,q 为不同节点且均存在于给定的二叉搜索树中。

如:root = [6,2,8,0,4,7,9,null,null,3,5] ;
节点 2 和 节点 8 的最近公共祖先就是节点 6;
节点 2 和 节点 5 的最近公共祖先就是节点 2;
在这里插入图片描述

2. 思路

方法:迭代法
二叉搜索树也叫二叉排序树。其特点是根节点的左子树值小于或等于根节点值,右子树值大于或等于根节点值。二叉搜索树也可能是一颗空树,但只要不空就满足以上条件。

基于以上对二叉搜索树的理解,可以提炼出以下几个要点。

  1. 对于任意节点 p 或者 q。大的节点大于等于根节点,小的节点小于等于根节点时。它们的公共祖先就是根节点。比如节点 2<= 节点 6。节点 8>= 节点 6,根节点即为 6;节点4 <= 节点6,节点 7>= 节点 6,根节点也为 6。
  2. 如果两个节点均小于根节点 6。则其最近祖先节点一定在左子树上。那么把根节点(节点6)左子树(节点2)作为根节点继续判断,以此迭代。
  3. 如果两个节点均大于根节点 6。则其最近祖先节点一定在右子树上。那么把根节点(节点6)右子树(节点8)作为根节点继续判断,以此迭代。

基于以上的分析,可使用迭代法。

3. 代码

 //构造函数如下
    function TreeNode(val) {
         this.val = val;
         this.left = this.right = null;
    }
 //原始数据如下
 var root = [6,2,8,0,4,7,9,null,null,3,5] 
 //变形后的数据结构如下
    var tree = {val:6,
        left: {val:2,left:{val:0,left: null,right:null}, right:{val:4,left:{val:3,left:null,right:null}, right:{val:5,left:null,right:null}}},
        right:{val:8, left:{val:7,left:null,right:null},right:{val:9,left:null,right:null}}
    };
    let lowestCommonAncestor = function(root, p, q) {
        let temp = root;
        //如果p>q,调换 p,q 的顺序
        if(p.val > q.val) {
            [p, q] = [q, p];
        }
        while(true) {
            //根元素大于等于大的元素值并且小于等于小的元素值,或者根元素为pq的任意一个,则直接返回根(顶层)元素
            if((temp.val >= p.val && temp.val <= q.val) || (temp === p || temp === q)) {
                return temp;
            //p,q均大于根元素,则说明pq都在根元素的右子树。则把根元素的右子树作为根元素循环
            } else if(temp.val < p.val && temp.val < q.val) {
                temp = temp.right;
            //p,q均小于根元素,则说明pq都在根元素的左子树。则把根元素的左子树作为根元素循环
            } else {
                temp = temp.left;
            }
        }
    };
    console.log(lowestCommonAncestor(tree,new TreeNode(9),new TreeNode(7)))
发布了252 篇原创文章 · 获赞 2360 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/103741010
今日推荐