LeetCode236 Lowest Common Ancestor of a Binary Tree

题目链接:

https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/

题目描述:

给一棵树,找两结点的最近公共祖先。

3
/ \
5 1
/ \ / \
6 2 0 8
/ \
7 4

LCA of nodes 5 and 1 is 3

LCA of nodes 5 and 4 is 5

题目分析:

设置两个标记变量pFind,qFind,当递归从根结点往下找,如果没有找到root与p或q相等,就让ptr_p和ptr_q随root一起变化,如果找到结点与p,标记pFind找到,这样当继续往下找的时候,ptr_p就不再改变,除非又回到ptr_p的上一层,当pFind与qFind都标记找到时,就可以不断的返回上一层找公共祖先。因为pFind或qFind单个标记找到时,往下找ptr_p或ptr_q不会再改变,这样就保证了只有往上找即找祖先时,才会出现ptr_p与ptr_q相等的情况(即是之前ptr_q与ptr_p随root一起变化时)。

第二次:
隔了几个月又来写这道题了,温故而知新。其实在普通树里面找两个节点的最近公共祖先。假设对于一个节点,如果在它的右子树里面只找到了其中一个目标节点,而在它的左子树中没有找到另一个目标节点,那么当前节点就不是目标节点的最近公共祖先了,但是如果在它的左子树中找到另一个目标节点,那么当前节点就是目标节点的公共祖先了。
所以,我们可以从叶子节点向上,标记子树中出现目标节点的情况。若一个节点的左右子树都有标记,则当前节点就是目标节点。

代码:
class Solution {
public:
    bool pFind=false;
    bool qFind=false;
    bool flag=false;
    void findLowestCommonAncestor(TreeNode* root,TreeNode* &LCA, TreeNode* ptr_p, TreeNode* ptr_q, TreeNode* p, TreeNode* q){
      if (root != NULL){
            if (pFind && qFind){
                return;
            }
            if (!pFind){
                ptr_p = root;
            }
            if (!qFind){
                ptr_q = root;
            }
            if (root == p){
                pFind = true;
            }
            if (root == q){
                qFind = true;
            }
            findLowestCommonAncestor(root->left,LCA, ptr_p, ptr_q, p, q);
            findLowestCommonAncestor(root->right,LCA, ptr_p, ptr_q, p, q);
            if (!flag && pFind && qFind && ptr_p == ptr_q){
                flag = true;
                LCA = ptr_p;
            }
      }
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        TreeNode* LCA = NULL;
        findLowestCommonAncestor(root,LCA, root, root, p, q);
        return LCA;
    }
};

ps:太二了,写的时候还在想递归返回结点,结点岂不是要一直改变,咋把LCA返回,蠢哭,传个引用就好了啊。

第二次:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==NULL || root==p || root==q){
            return root;
        }
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        if(left!=NULL && right!=NULL){
            return root;
        }
        return left==NULL? right:left;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值