LeetCode-----第二百三十六题-----二叉树的最近公共祖先

二叉树的最近公共祖先

难度:中等

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

百度百科中最近公共祖先的定义为:“对于有根树 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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值