【每日一题】节点与其祖先之间的最大差值
1026. 节点与其祖先之间的最大差值
关键词:图论、深度优先
题目来源:1026. 节点与其祖先之间的最大差值 - 力扣(Leetcode)
题目描述
T图论
T深度优先
给定二叉树的根节点 root,找出存在于不同节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。
(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)
输入:root = [8,3,10,1,6,null,14,null,null,4,7,13]
输出:7
输入:root = [1,null,2,null,0,3]
输出:3
数据范围
树中的节点数在 2 到 5000 之间。
0 <= Node.val <= 105
问题分析
此类问题,朴素的想法就是,找到一种遍历策略,将所有可能的情况全枚举一遍。在本问题中就是,求出每个结点与其所有祖先的距离的最大值。
设点对(x, y),其中x是y的祖先,其构成的值为|x-y|,去掉绝对值,要么是(x-y),要么是(y-x)
- 对于(x-y),若y的祖先中还有比x更大的结点,显然(x-y)就不是y到其所有祖先的距离的最大值
- 对于(y-x),若y的祖先中还有比x更小的结点,显然(y-x)就不是y到其所有祖先的距离的最大值
于是,我们发现,结点y到与其所有祖先的距离的最大值必然会在abs(y-minV)和abs(y-maxV)中产生。
于是,在计算y前,只需要知道y祖先结点的最大值和最小值即可,这正符合深度优先遍历的特点。
时间复杂度:O(n)
空间复杂度:O(n)
代码实现
int dfs(TreeNode *u, int minV, int maxV) {
if (!u)return 0;
// 求当前结点与其祖先结点的最大差值
int dis = max(abs(u->val - minV), abs(u->val - maxV));
// 求u的左右孩子的祖先结点的最小值和最大值
minV = min(u->val, minV), maxV = max(u->val, maxV);
// 求左右子树中的结点与其各自祖先结点的最大差值
dis = max(dfs(u->left, minV, maxV), dis);
dis = max(dfs(u->right, minV, maxV), dis);
// 每个结点与其祖先结点的最大差值
return dis;
}
int maxAncestorDiff(TreeNode *root) {
return dfs(root, root->val, root->val);
}

浙公网安备 33010602011771号