1123. 最深叶节点的最近公共祖先
题意
- 返回最深节点的最近公共祖先;
- 每个节点的
val
互不相同; - 节点最多 1000 个;
解法1 bfs + 回溯
和经典的 LCA 不同的是,这里的对象是 若干个叶节点(1个或多个,最深的)。
- 首先将最深的叶节点找出来:
bfs
广搜,用map
存储每层的节点 - 记录所有节点的父节点:
father
数组(在bfs
广搜的同时进行) - 然后回溯最深叶节点的父节点,寻找最近公共祖先(用 map 记录每个父节点的出现次数,因为回溯是倒着回溯的,所以第一个出现次数 =
mp[maxLayer].size()
的一定是最近公共祖先) - 如果最深层叶节点只有一个,那么他的最近公共祖先是他本身。
ps. 由于 每个节点的 val 互不相同,所以可以以 val
作为 father
数据的下标。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
unordered_map<int, vector<TreeNode*> > mp;
vector<TreeNode*> father = vector<TreeNode*>(1010);
void bfs(TreeNode* root, int layer)
{
if(root == nullptr) return;
mp[layer].emplace_back(root); // 维护每层的节点
// 记录父节点
if(root->left) father[root->left->val] = root;
if(root->right) father[root->right->val] = root;
bfs(root->left, layer+1);
bfs(root->right, layer+1);
}
TreeNode* lcaDeepestLeaves(TreeNode* root) {
father[root->val] = new TreeNode(-1); // 根节点标记
bfs(root, 0);
int maxLayer = 0;
for(auto x : mp)
{
if(x.first > maxLayer) maxLayer = x.first; // 寻找最深层
}
if(mp[maxLayer].size() == 1) return mp[maxLayer][0]; // 最深叶节点只有一个
unordered_map<int, int> tmp;
for(auto n : mp[maxLayer])
{
int curNode = n->val;
while(curNode != -1) // 回溯父节点
{
tmp[father[curNode]->val]++;
if(tmp[father[curNode]->val] == mp[maxLayer].size())
{
return father[curNode];
}
curNode = father[curNode]->val;
}
}
return nullptr;
}
};
复杂度
时间复杂度:O(n),bfs 遍历每个节点。
空间复杂度:O(d),递归栈的大小等于树的深度。
解法2 递归
比较左右子树的深度:文章来源:https://www.toymoban.com/news/detail-708249.html
- 若左子树深,则 lca 为左子树的 lca;
- 若右子树深,则 lca 为右子树的 lca;
- 若左右子树一样深,则 lca 为当前节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
pair<TreeNode*, int> f(TreeNode* root)
{
if(root == nullptr) return {root, 0};
auto left = f(root->left);
auto right = f(root->right);
if(left.second > right.second) // 左子树深
{
return {left.first, left.second + 1};
}
if(left.second < right.second) // 右子树深
{
return {right.first, right.second + 1};
}
return {root, left.second + 1};
}
TreeNode* lcaDeepestLeaves(TreeNode* root) {
return f(root).first;
}
};
复杂度
时间复杂度:O(n),遍历每个节点。
空间复杂度:O(d),递归栈的大小等于树的深度。文章来源地址https://www.toymoban.com/news/detail-708249.html
到了这里,关于【LeetCode - 每日一题】1123. 最深叶节点的最近公共祖先(23.09.06)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!