leetcode-二叉树的最近公共祖先

点击:题目链接:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科:最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

思路

根据题意,我们可以直接想到数组的后序遍历的特点。先判断它的子节点,最后再判断根节点。

由于题目中节点可能分散在树的各个地方,所以我们要注意以下几个判断条件:

  • 如果一棵子树的两个节点就是所给的节点,则该子树的根节点就是公共祖先
  • 如果一棵子树的其中一个节点是,那就要继续要往上继续判断,同时要标记当前子树根节点是包含所要的节点。
  • 如果子树的根节点和其子节点都是指定的节点,则该根节点也是公共祖先

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 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 ans;
}

private:
TreeNode* ans;
bool dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == nullptr) return false;

bool leftNode = dfs(root->left, p, q);
bool rightNode = dfs(root->right, p, q);

if ((leftNode && rightNode) || ((root->val == p->val) || (root->val == q->val) && (leftNode || rightNode))) {
ans = root;
}

return ((leftNode || rightNode) || (root->val == p->val) || (root->val == q->val));
}
};

复杂度

时间O(N),空间 O(N)

思路

我们也可以,将指定的节点,带入去扫描树,首先找到其中一个指定节点在树的位置,然后不断找到父节点。然后再找另一个指定点,不断找父节点,若找到一样的点,则该点就是最大公共祖先。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
Nodes[root->val] = nullptr;
dfs(root);

while (p) {
vis[p->val] = true;
p = Nodes[p->val];
}

while (q) {
if (vis[q->val]) return q;
q = Nodes[q->val];
}
return nullptr;

}

private:
TreeNode* ans;
map<int, TreeNode*> Nodes;
map<int, bool> vis;

void dfs(TreeNode* root) {
if (root->left) {
Nodes[root->left->val] = root;
dfs(root->left);
}

if (root->right) {
Nodes[root->right->val] = root;
dfs(root->right);
}
}
};

复杂度

时间 O(N), 空间用到2N,所以O(N)

作者

Dylan Zhu

发布于

2021-04-07

更新于

2021-04-07

许可协议

评论

:D 一言句子获取中...