LeetCode 236:二叉树的最近公共祖先

看剑指Offer书上的解法,照葫芦画瓢写的程序,一开始运行出错,改了ans=*it1的顺序运行结果正确,但是提交后有case不通过:(代码的思路并没有完全理解)

经过第一次试用LeetCode在线调试工具,打印中间变量找到问题所在:搜索路径没有把目标节点本身加入进去。

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || !p || !q) return nullptr;

        vector<TreeNode*> vp, vq;
        findTargetNode(root, p, vp); vp.push_back(p);
        findTargetNode(root, q, vq); vq.push_back(q);
/*
        vector<TreeNode*>::iterator it = vp.begin();
        while(it!=vp.end()) {
            cout<<(*it)->val<<endl;
            it++;
        }
        vector<TreeNode*>::iterator it2 = vq.begin();
        while(it2!=vq.end()) {
            cout<<(*it2)->val<<endl;
            it2++;
        }
*/
        return findMaxCommom(vp, vq);
    }

    bool findTargetNode(TreeNode* root, TreeNode* p, vector<TreeNode*>& path) {
        if(root == nullptr) return false;
        if(root == p) return true;

        path.push_back(root);
        bool found = false;
        if(!found && root->left) found = findTargetNode(root->left, p, path);
        if(!found && root->right) found = findTargetNode(root->right, p, path);

        if(!found) path.pop_back();

        return found;
    }

    TreeNode* findMaxCommom(vector<TreeNode*> vp, vector<TreeNode*> vq) {
        vector<TreeNode*>::iterator it1 = vp.begin();
        vector<TreeNode*>::iterator it2 = vq.begin();

        TreeNode* ans = nullptr;
        while(it1!=vp.end() && it2!=vq.end() && *it1==*it2) {
            ans=*it1; it1++; it2++;
        }
        return ans;
    }
};

题解区非常简洁优美的递归解法:

两个节点p,q分为两种情况:

    p和q在相同子树中

    p和q在不同子树中
从根节点遍历,递归向左右子树查询节点信息
递归终止条件:如果当前节点为空或等于p或q,则返回当前节点

递归遍历左右子树,如果左右子树查到节点都不为空,则表明p和q分别在左右子树中,因此,当前节点即为最近公共祖先;
如果左右子树其中一个不为空,则返回非空节点。

(从递归回退的角度去考虑,更容易理解)

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || root==p || root==q) 
         return root;

        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right= lowestCommonAncestor(root->right, p, q);

        if(left && right) {
            return root;
        }
        return left? left:right;
    }
};
发布了97 篇原创文章 · 获赞 11 · 访问量 2480

猜你喜欢

转载自blog.csdn.net/chengda321/article/details/103266862