给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
#include <iostream>
using namespace std;
// 二叉树节点结构
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// 如果当前节点为空,返回nullptr
if (root == nullptr) return nullptr;
// 如果当前节点等于p或q,则当前节点就是它们的最近公共祖先
if (root == p || root == q) return root;
// 在左子树中查找p和q的最近公共祖先
TreeNode* left = lowestCommonAncestor(root->left, p, q);
// 在右子树中查找p和q的最近公共祖先
TreeNode* right = lowestCommonAncestor(root->right, p, q);
// 如果左右子树分别找到了p和q,则当前节点就是它们的最近公共祖先
if (left && right) return root;
// 如果只在左子树中找到了p或q,则返回左子树中找到的节点
// 如果只在右子树中找到了p或q,则返回右子树中找到的节点
return left ? left : right;
}
};
int main() {
// 创建二叉树
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(5);
root->right = new TreeNode(1);
root->left->left = new TreeNode(6);
root->left->right = new TreeNode(2);
root->left->right->left = new TreeNode(7);
root->left->right->right = new TreeNode(4);
root->right->left = new TreeNode(0);
root->right->right = new TreeNode(8);
// 创建解决方案对象
Solution solution;
// 指定节点p和q
TreeNode* p = root->left;
TreeNode* q = root->right;
// 找到最近公共祖先
TreeNode* ancestor = solution.lowestCommonAncestor(root, p, q);
// 输出结果
if (ancestor != nullptr) {
cout << "The lowest common ancestor of " << p->val << " and " << q->val << " is " << ancestor->val << endl;
} else {
cout << "No common ancestor found." << endl;
}
// 释放内存
delete root->left->right->right;
delete root->left->right->left;
delete root->left->right;
delete root->left->left;
delete root->left;
delete root->right->left;
delete root->right->right;
delete root->right;
delete root;
return 0;
}
递归查找逻辑:
首先检查当前节点是否为空,如果是,则返回nullptr。然后,检查当前节点是否等于p或q,如果是,则当前节点就是它们的最近公共祖先。接着递归地在左子树和右子树中查找p和q的最近公共祖先。如果左右子树分别找到了p和q,则当前节点就是它们的最近公共祖先。如果只在左子树或右子树中找到了p或q,则返回左子树或右子树中找到的节点。