3.【二叉树】最近公共祖先

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

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

输入 [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8

输出 6

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    
    bool visit(TreeNode* root, TreeNode* p, TreeNode* q){
        
        if(!root) return NULL;
        if(root==p||root==q)  return true;
        return visit(root->left,p,q)||visit(root->right,p,q);//如果左递归找到了p返回1,
//右递归如果也返回1,找到的必定是q
        }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        
        if(!root) return NULL;
        if(root==p||root==q){
            if(visit(root->left,p,q)||visit(root->right,p,q)) return root;
        }
        if(visit(root->left,p,q)&&visit(root->right,p,q)) return root;
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        if(left) return left;
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        if(right) return right;
        return NULL;
        
   
    }
};

最近公共祖先结点:若该的左右子树能够遍历到p,q结点,则该结点为最近公共祖先。

所以从根结点开始,前序遍历寻找该结点。

如果根结点是p,q中的一个,则只要左子树或者右子树能够遍历到另一结点即可。(不会重复遍历到同一结点)

如果不是,则遍历左右子树。

主要看visit()函数:eg:对root->left结点遍历只要找到了一个p/q,就返回1,并且 对root->left结点遍历只要找到了另一个q/p,则满足条件。

还有一点需要注意,如果只写两个    lowestCommonAncestor(root->left,p,q);   lowestCommonAncestor(root->right,p,q);结果是返回的NULL。

需要添加:如果左递归返回了一个值,则返回,程序结束;如果右递归返回了一个值,则返回,程序结束;

猜你喜欢

转载自www.cnblogs.com/apo2019/p/10775677.html