val 互不相同;和经典的 LCA 不同的是,这里的对象是 若干个叶节点(1个或多个,最深的)。
bfs 广搜,用 map 存储每层的节点father 数组(在 bfs 广搜的同时进行)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),递归栈的大小等于树的深度。
比较左右子树的深度:
/**
* 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),递归栈的大小等于树的深度。