解:先求出整颗树的dfs序,同时求出各个结点的深度。通过转化我们把树上的询问变为了序列的处理,深度代表这个点的权值。这样就把删除某颗子树变为了删除某个区间,然后我们只需要在这个区间之外的地方找到最大的权值即可。用前后缀来记录某个结点之前与之后的最大权值,我们就可以O(1)来回答每个询问。
class Solution {
public:
vector<int> treeQueries(TreeNode* root, vector<int>& queries) {
int idx=0,h=0;
vector<int> l,r;
vector<int> dep({0});//0作为前哨兵
function<void(TreeNode*,int)> dfs=[&](TreeNode* root,int curh){
dep.push_back(curh);
l.resize(max((int)l.size(),root->val+1));
r.resize(max((int)r.size(),root->val+1));
l[root->val]=++idx;
if(root->left) dfs(root->left,curh+1);
if(root->right) dfs(root->right,curh+1);
r[root->val]=idx;
};
dfs(root,0);
dep.push_back({0});//0作为后哨兵
int n=dep.size()-2;
vector<int> sl(n+2),sr(n+2);//前后缀
for(int i=1;i<=n;i++) sl[i]=max(sl[i-1],dep[i]);
for(int i=n;i;i--) sr[i]=max(sr[i+1],dep[i]);
vector<int> ans;
for(auto q:queries){
ans.push_back(max(sl[l[q]-1],sr[r[q]+1]));
}
return ans;
}
};
时间复杂度:O(n)。
空间复杂度:O(n),n为结点个数。

博客介绍了移除子树后的二叉树高度的求解方法。先求出整颗树的dfs序和各结点深度,将树上询问转化为序列处理,把删除子树变为删除区间,通过前后缀记录最大权值,可O(1)回答询问,时间和空间复杂度均为O(n)。
535

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



