难度:中等
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点5
和节点1
的最近公共祖先是节点3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点5
和节点4
的最近公共祖先是节点5。
因为根据定义最近公共祖先节点可以为节点本身。
题目解析:
这个和上一题最大的区别就是本题的二叉树不是搜索二叉树,里面的元素是没有规律的,乱序的。唯一保证的是里面的元素不重复。解题思路是使用后序递归遍历,遍历到root和p,q中任意一个相等时,就置为true,否则置为false。当子节点中任意一个为true时,父节点为true,当两个子节点都为true时,或者当前root等于p,q其中一个,并且左孩子或者有孩子为true时,这个节点就是最近祖先节点。
参考代码:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <deque>
#include <stack>
#include <algorithm>
#include <map>
#include <assert.h>
#include <memory>
#include<queue>
#include<functional>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* res;
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//使用后序遍历 左右根
back_search(root, p, q);
return res;
}
//后序遍历
bool back_search(TreeNode* root, TreeNode* p, TreeNode* q)
{
//结束条件
if (root == NULL)
return false;
bool left_flag = back_search(root->left, p, q); //左
bool right_flag = back_search(root->right, p, q);//右
//根,条件判断。1.两个节点分别在当前root的左右两边;2.有一个节点和当前root匹配,另一个节点在当前节点的左边或者右边
if ((left_flag && right_flag) || (root->val == p->val || root->val == q->val) && (left_flag || right_flag))
{
res = root; //记录符合条件的root
}
//如果当前节点和其中一个节点匹配,或者当前节点的左右边有匹配的话就返回true
return left_flag || right_flag || root->val == p->val || root->val == q->val;
}
};
int main()
{
Solution solution;
TreeNode TreeNode1(3);
TreeNode TreeNode2(5);
TreeNode TreeNode3(1);
TreeNode TreeNode4(6);
TreeNode TreeNode5(2);
TreeNode TreeNode6(0);
TreeNode TreeNode7(8);
TreeNode TreeNode8(7);
TreeNode TreeNode9(4);
TreeNode1.left = &TreeNode2;
TreeNode1.right = &TreeNode3;
TreeNode2.left = &TreeNode4;
TreeNode2.right = &TreeNode5;
TreeNode3.left = NULL;
TreeNode3.right = NULL;
TreeNode4.left = NULL;
TreeNode4.right = NULL;
TreeNode5.left = &TreeNode8;
TreeNode5.right = &TreeNode9;
TreeNode6.left = NULL;
TreeNode6.right = NULL;
TreeNode7.left = NULL;
TreeNode7.right = NULL;
TreeNode8.left = NULL;
TreeNode8.right = NULL;
TreeNode9.left = NULL;
TreeNode9.right = NULL;
TreeNode p(5);
TreeNode q(4);
solution.lowestCommonAncestor(&TreeNode1,&p,&q);
system("pause");
return 0;
}