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;
    }
};

你可能感兴趣的:(LeetCode,树,236)