剑指 Offer 68 - II. 二叉树的最近公共祖先 && Leetcode 236. 二叉树的最近公共祖先

地址  https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/

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

百度百科中最近公共祖先的定义为:“对于有根树 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。因为根据定义最近公共祖先节点可以为节点本身。
 

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。
注意:本题与主站 236 题相同:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

 解答 同样是树的遍历

但是二叉树要比二叉搜索书更加复杂

因为不能依据搜索节点的值与当前节点比较而判断搜索节点是在当前节点的左子树或者右子树或者一边一个节点

我们只能两边子树均进行搜索比对

添加一个变量num  记录左子树和右子树出现搜索节点的数目

类似上一题,搜索节点和当前节点的相对位置可以分为以下几种情况

1 两搜索点均在当前节点两边,当前节点就是答案

2 两搜索点在当前节点同一边,因为不同于二叉树,我们要遍历完当前节点的所有子树后才能确认搜索点的位置,

所以是在回溯的时候确认两搜索点在当前节点同一边,这时候应该已经得到了答案。不予处理  .

3 当前节点就是搜索节点,如果另一节点已经搜索到 返回当前节点

class Solution {
public:
    TreeNode* ans = NULL;
    int dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL) return 0;
        
        int lfind = dfs(root->left, p, q);
        int rfind = dfs(root->right, p, q);
        
        int ret = lfind + rfind;
        if (p->val == root->val ||q->val == root->val ) ret++;
        if (ret == 2 && ans == NULL) { ans = root; }
        return ret ;
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        dfs(root, p, q);
        return ans;
    }
};

 

posted on 2021-03-06 13:32  itdef  阅读(81)  评论(0编辑  收藏  举报

导航