递归:
时间复杂度:,其中n是二叉树结点个数
空间复杂度:,其中n是栈的深度,也是二叉树结点个数
/**
* 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) {
dfs(root, p, q);
return res;
}
bool dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root) return false;
bool lb = dfs(root->left, p, q);
bool rb = dfs(root->right, p, q);
if ((lb && rb) || ((lb || rb) && (root == p || root == q))) {
res = root;
}
return lb || rb || root == p || root == q;
}
private:
TreeNode* res;
};
两次循环遍历:
因为有公共祖先,所以就是有公共结点,只需将两个点沿路的店插入进数组,然后在沿路遍历找到相同点即可
时间复杂度:,其中n是二叉树结点个数
空间复杂度:,其中n是二叉树结点个数
/**
* 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) {
vector<TreeNode*> ppath = GetPath(root, p);
vector<TreeNode*> qpath = GetPath(root, q);
TreeNode* res;
for (int i = 0; i < ppath.size() && i < qpath.size(); ++i) {
if (ppath[i] == qpath[i]) {
res = ppath[i];
}
}
return res;
}
vector<TreeNode*> GetPath(TreeNode* root, TreeNode* k) {
vector<TreeNode*> res;
while (root != k) {
res.push_back(root);
if (k->val < root->val) {
root = root->left;
}
else {
root = root->right;
}
}
res.push_back(root);
return res;
}
};
一次循环遍历:
其实可以直接沿按照值往下找,因为是二叉搜索树,所以性质是左子树小于中间结点,中间结点小于右子树
时间复杂度:,其中n是二叉树结点个数
空间复杂度:
/**
* 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) {
TreeNode* res;
while (root) {
if (root->val > p->val && root->val > q->val) {
root = root->left;
}
else if (root->val < p->val && root->val < q->val) {
root = root->right;
}
else {
return root;
}
}
return nullptr;
}
};