这是一道LCA问题,同时,是一道只查询一次的最近公共祖先。
我使用了BFS+哈希存储父节点的方式,实现了O(n+h)复杂度解决问题。
通过BFS遍历树,将每个节点的父节点,存入哈希映射中(key为节点,value为其父节点),再以两个给的节点作为起点,回溯找其公共最近的父节点输出。
同时,我对其做了一些优化:
1.在BFS时,只要我遍历到了2个目标节点,存储其父节点后,就直接停止遍历。因为二者的公共祖先不可能在它们的更深层。
2.在回溯找祖先时,我根据二者层的深度,优先回溯深层的,因为这可以更快的找到其最近的祖先,相比于使用hashset。
还有一些进阶的方法来解决这个问题,比如使用ST表,但是那些是针对于多次查询静态树的方法,在这里使用不太合适,而且ST表建表是O(nlogn),比线性的复杂度高,因此这里不太适合ST表。还有Tarjan 并查集,但这个我不会。

我的代码:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
queue<TreeNode*> qu;
unordered_map<TreeNode*,TreeNode*> mp;
unordered_map<int,int> hm;
qu.push(root);
int flag=0;
TreeNode *t;
hm[root->val]=0;
while(!qu.empty())
{
if(flag==2) break;
t=qu.front();
if(t==p||t==q) flag++;
if(t->left)
{
qu.push(t->left);
mp[t->left]=t;
hm[t->left->val]=hm[t->val]+1;
}
if(t->right)
{
qu.push(t->right);
mp[t->right]=t;
hm[t->right->val]=hm[t->val]+1;
}
qu.pop();
}
TreeNode *c1=p,*c2=q;
int a1=p->val,a2=q->val;
while(c1!=c2)
{
if(hm[c1->val]>=hm[c2->val]) c1=mp[c1];
else c2=mp[c2];
}
return c1;
}
};
&spm=1001.2101.3001.5002&articleId=144201255&d=1&t=3&u=1d3bf63ad0f844aca3a9e84c9ba1877e)
916

被折叠的 条评论
为什么被折叠?



