给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
_______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 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 为不同节点且均存在于给定的二叉树中。
/** * 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) { //思路:递归记录根到节点的路径,再同时遍历两个路径,找到最近的共同节点 //步骤:1.先求出p节点的路径;2.清除finish与path;3.求出q节点的路径 //4.比较两段路径的长短,短的为最终长度len;5.遍历两段路径(长度为len),当遇见相等则为最近的公共祖先 vector<TreeNode*>path; vector<TreeNode*>node_p_path; vector<TreeNode*>node_q_path; int finish = 0; preorder(root, p, path, node_p_path, finish); path.clear(); 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 = 0; for (int i = 0; i < path_len; i ++) { if(node_p_path[i] == node_q_path[i]) { result = node_p_path[i]; } } return result; } //根节点到某个节点的路径 private: 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(); } };