LeetCode 236. Lowest Common Ancestor of a Binary Tree(求两个结点的LCA)

题目链接:点击这里

在这里插入图片描述
在这里插入图片描述
来一个最鲁莽的做法,码力十足

分析:

  1. 两个节点的公共祖先一定在从根节点至这两个节点的路径上。
  2. 公共祖先中的最近公共祖先,即同时出现在这两条路径上的离根节点最远的节点 (或离两个最近) 。
  3. 最终算法:求出p节点路径 和 q节点路径,然后找到两路径上最后一个相同的节点。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
	//求根节点到某结点的路径(深度遍历)
    //node正在遍历的结点,search带搜索的结点,path路径栈,result存储路径结果,finish记录是否找到 
    void preorder(TreeNode* node, TreeNode* search, vector<TreeNode*> &path, vector<TreeNode*> &result, int &finish)
    {
        if(!node || finish)	return;
        
        path.push_back(node);
        
        if(node==search)
        {
            finish = 1;
            result = path;
        }
        
        preorder(node->left, search, path, result, finish);
        preorder(node->right, search, path, result, finish);
        
        path.pop_back();
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        vector<TreeNode*> path; //临时栈
        vector<TreeNode*> node_p_path;  //存储结点p的路径
        vector<TreeNode*> node_q_path;  //存储结点q的路径
        
        int finish = 0;
        preorder(root, p, path, node_p_path, finish);

        path.clear();   //清空path、finish
        finish = 0;

        preorder(root, q, path, node_q_path, finish);
        
        int path_len = 0;   //较短路径的长度
        if(node_p_path.size() < node_q_path.size())
            path_len = node_p_path.size();
        else
            path_len = node_q_path.size();
        
        //同时遍历两条路径上的结点,找到最近公共祖先
        TreeNode* result = NULL;
        for(int i = 0 ; i < path_len; i++)
            if(node_p_path[i]==node_q_path[i])
                result = node_p_path[i];
        return result;
    }
};

递归思路:

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

  1. p和q在相同子树中
  2. p和q在不同子树中

从根节点遍历,递归向左右子树查询节点信息。

递归终止条件:如果当前节点为空或等于p或等于q,则返回当前节点。

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

注意LeetCode迷之报错:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
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)  return right;           //如果p,q仅在右子树
        else if(right==NULL)    return left;    //如果p,q仅在左子树
        else    return root;                    //如果p,q在左右两个子树上
    }
};
发布了694 篇原创文章 · 获赞 104 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104076723