leetcode1373. 二叉搜索子树的最大键值和
作者:互联网
原题链接:https://leetcode.cn/problems/maximum-sum-bst-in-binary-tree/
给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。
二叉搜索树的定义如下:
- 任意节点的左子树中的键值都 小于 此节点的键值。
- 任意节点的右子树中的键值都 大于 此节点的键值。
- 任意节点的左子树和右子树都是二叉搜索树。
示例 1:
输入:root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
输出:20
解释:键值为 3 的子树是和最大的二叉搜索树。
思路:
创建一个结构体,存储每一个节点的三种信息:以该节点为根节点的和、最大值以及最小值。在遍历到每一个节点时,需要比较其左子树的最大值是否小于当前节点的值,并且当前节点的值是否小于右子树的最小值。如果满足这个条件,则说明该节点为二叉搜索树,该二叉搜索树的和=左子树和+右子树和+当前节点值,最大值=max(右子树的最大值,当前节点值),最小值=min(左子树的最小值,当前节点值)。否则其和=-INF,最大值=-INF,最小值=INF,这样使得只要包含这个节点的树都不满足二叉搜索树的条件。
代码:
/** * 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: struct T { int sum, mmin, mmax; T(int _sum, int _mmin, int _mmax): sum(_sum), mmin(_mmin), mmax(_mmax){} }; const int INF = 1e5; int ans = 0; T dfs(TreeNode* root) { if(!root) return {0, INF, -INF}; T left = dfs(root->left); T right = dfs(root->right); if(left.mmax < root->val && root->val < right.mmin) { int s = left.sum + root->val + right.sum; ans = max(s, ans); return {s, min(left.mmin, root->val), max(right.mmax, root->val)}; } return {-INF, INF, -INF}; } int maxSumBST(TreeNode* root) { dfs(root); return ans; } };
注:如果遍历到的节点为空,说明该节点是叶子节点的子树,那么为了满足二叉搜索树的性质,应该将其和设为0,最小值为INF,最大值为-INF,这样每个叶子节点都满足二叉搜索树的条件。但是这样在统计叶子节点最小值和最大值时会有问题,因为此时的最小值是左子树的最小值,即INF,最大值为右子树的最大值,即-INF,这样很显然是错误的。因此在面对左子树为空或者右子树为空的情况下,叶子节点的最小值应该为min(左子树的最小值,当前节点值),最大值为max(右子树的最大值,当前节点值),从而消掉空节点的INF和-INF。
标签:子树,int,leetcode1373,right,键值,INF,root,节点,left 来源: https://www.cnblogs.com/cvxer/p/16687394.html