LC 6223.移除子树后的二叉树高度(dp ||dfs序)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LC 6223.移除子树后的二叉树高度(dp ||dfs序)相关的知识,希望对你有一定的参考价值。
LC 6223.移除子树后的二叉树高度(dp ||dfs序)
思路1.dfs序
显然子树问题可以用dfs序转成区间问题。
本题可以转的原因,删除一个子树,相当删除一个子树,而除了该子树外的其他点都可以从根节点走到(题目保证根不会被删)。因此每次询问就剩下一个前缀和后缀,取他们两的最大值就是答案,这个值定义为每个结点的深度。
时间复杂度: O ( n ) O(n) O(n)
/**
* 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
int n = 0, clk = 0;
vector<int> A, L, R;
void dfs(TreeNode *node, int d)
// 没有输入 n,只好动态计算 n 的大小并扩充列表...
int idx = node->val;
n = max(idx, n);
while (A.size() <= n) A.push_back(0), L.push_back(0), R.push_back(0);
// node 是第 clk 个被访问的点
clk++;
// A[i] 表示第 i 个被访问的点的深度
A[clk] = d;
// L[i] 表示第 i 个点的子树对应的连续区间的左端点
L[idx] = clk;
// DFS 子树
if (node->left != nullptr) dfs(node->left, d + 1);
if (node->right != nullptr) dfs(node->right, d + 1);
// R[i] 表示第 i 个点的子树对应的连续区间的右端点
R[idx] = clk;
public:
vector<int> treeQueries(TreeNode* root, vector<int>& queries)
dfs(root, 0);
// f[i] 表示 max(A[1], A[2], ..., A[i])
// g[i] 表示 max(A[n], A[n - 1], ..., A[i])
vector<int> f(n + 2), g(n + 2);
for (int i = 1; i <= n; i++) f[i] = max(f[i - 1], A[i]);
for (int i = n; i > 0; i--) g[i] = max(g[i + 1], A[i]);
vector<int> ans;
// 树上询问转为区间询问处理
for (int x : queries) ans.push_back(max(f[L[x] - 1], g[R[x] + 1]));
return ans;
;
思路2 dp
先预处理出每个子树的最大高度,这个可以递归。
然后dfs,从根开始枚举删掉某个子树后的答案,显然就是从根开始到此节点的深度+val(另一个结点) (之前预处理的高度)
时间复杂度: O ( n ) O(n) O(n)
class Solution
public:
vector<int> treeQueries(TreeNode *root, vector<int> &queries)
unordered_map<TreeNode*, int> height; // 每棵子树的高度
function<int(TreeNode*)> get_height = [&](TreeNode *node) -> int
return node ? height[node] = 1 + max(get_height(node->left), get_height(node->right)) : 0;
;
get_height(root);
int res[height.size() + 1]; // 每个节点的答案
function<void(TreeNode*, int, int)> dfs = [&](TreeNode *node, int depth, int rest_h)
if (node == nullptr) return;
++depth;
res[node->val] = rest_h;
dfs(node->left, depth, max(rest_h, depth + height[node->right]));
dfs(node->right, depth, max(rest_h, depth + height[node->left]));
;
dfs(root, -1, 0);
for (auto &q : queries) q = res[q];
return queries;
;
以上是关于LC 6223.移除子树后的二叉树高度(dp ||dfs序)的主要内容,如果未能解决你的问题,请参考以下文章