方法一:DFS、路径比较
1、利用深度优先搜索分别获取两个结点在二叉树中的路径;
2、比较两个路径,得到最后相同的的结点即为两个结点的最近公共祖先。
时间复杂度:o(n)。最坏情况需要遍历二叉树所有节点
空间复杂度:o(n)。
class Solution { public: bool flag = false; //深度优先搜索(dfs) void dfs(TreeNode* root, vector<int>& path, int target) { if (root == nullptr || flag == true) return; path.push_back(root->val); if (root->val == target) { flag = true; return; } dfs(root->left, path, target); dfs(root->right, path, target); if (flag == true) return; //如果到达底部还未找到,回溯 path.pop_back(); } int lowestCommonAncestor(TreeNode* root, int o1, int o2) { vector<int> path1; vector<int> path2; dfs(root, path1, o1); //重置flag寻找下一个 flag = false; dfs(root, path2, o2); int num; //寻找最后一个相同的结点 for (int i = 0; i < path1.size() && i < path2.size(); i++) { if (path1[i] == path2[i]) num = path1[i]; } return num; } };
方法二:递归
- step 1:如果o1和o2中的任一个和root匹配,那么root就是最近公共祖先。
- step 2:如果都不匹配,则分别递归左、右子树。
- step 3:如果有一个节点出现在左子树,并且另一个节点出现在右子树,则root就是最近公共祖先.
- step 4:如果两个节点都出现在左子树,则说明最低公共祖先在左子树中,否则在右子树。
- step 5:继续递归左、右子树,直到遇到step1或者step3的情况。
时间复杂度:o(n)。
空间复杂度:o(n)。
class Solution { public: int lowestCommonAncestor(TreeNode* root, int o1, int o2) { //该子树没找到,返回-1 if(root == NULL) return -1; //该节点是其中某一个节点 if(root->val == o1 || root->val == o2) return root->val; //左子树寻找公共祖先 int left = lowestCommonAncestor(root->left, o1, o2); //右子树寻找公共祖先 int right = lowestCommonAncestor(root->right, o1, o2); //左子树为没找到,则在右子树中 if(left == -1) return right; //右子树没找到,则在左子树中 if(right == -1) return left; //否则是当前节点 return root->val; } };