给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树 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。
需要添加:如果左递归返回了一个值,则返回,程序结束;如果右递归返回了一个值,则返回,程序结束;