以下是题目描述:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
以下是题目示例:
题目是让我们找最近公共祖先,简单点说就是让我们找祖先,很简单就可以想到从子孙辈找是最容易找到祖先的,也就是从叶子节点找。那么又如何找到叶子节点呢?
自然就可以想到是递归遍历的思路。
以下是c++的代码:
#include <iostream>
using namaspace std;
//二叉树节点定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
}
//辅助函数,用于查找最近公共祖先
TreeNode* lowestCommonAncestorHelper(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL || p == root || q == root) {
return root;
}
//在左子树中查找p和q的最近公共祖先
TreeNode* left = lowestCommonAncestor(root->left, p, q);
//在右子树中查找p和q的最近公共祖先
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left && right) {
//如果p和q分别在左右子树中找到了最近公共祖先,则当前节点就是最近公共祖先
return root;
}else if(left){
//如果只在左子树中找到了最近公共祖先,则返回在左子树中的最近公共祖先
return left;
}else{
//如果只在右子树中找到了最近公共祖先,则返回在右子树中的最近公共祖先
return right;
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL || p == NULL || q == NULL) {
return nullptr;
}
return lowestCommonAncestorHelper(root, p, q);
}
以下是go语言的解法:
package main
import "fmt"
// TreeNode 二叉树节点的定义
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// lowestCommonAncestorHelper 辅助函数,用于查找最近公共祖先
func lowestCommonAncestorHelper(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
// 如果当前节点为空或等于p或q,则当前节点就是最近公共祖先
return root
}
// 在左子树中查找p和q的最近公共祖先
leftLCA := lowestCommonAncestorHelper(root.Left, p, q)
// 在右子树中查找p和q的最近公共祖先
rightLCA := lowestCommonAncestorHelper(root.Right, p, q)
if leftLCA != nil && rightLCA != nil {
// 如果p和q分别在左右子树中找到了最近公共祖先,则当前节点就是最近公共祖先
return root
} else if leftLCA != nil {
// 如果只在左子树中找到了最近公共祖先,则返回左子树中的最近公共祖先
return leftLCA
} else {
// 如果只在右子树中找到了最近公共祖先,则返回右子树中的最近公共祖先
return rightLCA
}
}
// lowestCommonAncestor 主函数,调用辅助函数查找最近公共祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || p == nil || q == nil {
return nil
}
return lowestCommonAncestorHelper(root, p, q)
}