(2022.02.22)每日一题 二叉搜索子树的最大键值和
今天去体检了。
⼆叉树相关题目最核⼼的思路是明确当前节点需要做的事情是什么。
如果当前节点要做的事情需要通过左右⼦树的计算结果推导出来,就要⽤到后序遍历。
这道题为什么⽤后序遍历呢?因为我们需要的这些变量都是可以通过后序遍历得到的。
你计算以 root 为根的⼆叉树的节点之和,可以通过左右子树的和加上 root.val 计算出来?
你计算以 root 为根的⼆叉树的最大值/最小值,是不是可以通过左右子树的最大值/最小值和 root.val 比较出来?
你判断以 root 为根的⼆叉树是不是 BST,是不是得先判断左右子树是不是 BST?是不是还得看看左右子树的最大值和最小值?
文章开头说过,如果当前节点要做的事情需要通过左右⼦树的计算结果推导出来,就要⽤到后序遍历。 因为以上⼏点都可以通过后序遍历的⽅式计算出来,所以这道题使⽤后序遍历肯定是最⾼效的。
我们想要计算子树中BST的最大和,我们需要做:
- 左右子树是否是BST,如果是了,那么加上根节点是否是BST?
- 左子树的最大值和右子树的最小值,有了这俩可以跟根节点进行比较,判断以该根节点的树是否是BST
- 左右子树的节点值和,如果上述条件满足,那么新的一棵BST就是左子树的和加右子树的和加当前根节点的值
class Solution {
private:
int maxSum = 0;
public:
int maxSumBST(TreeNode* root) {
traverse(root);
return maxSum;
}
//二叉排序树首先要是一棵二叉树
//设置一个数组,
// res[0] 是否是BST 是为1,否为0
// res[1] 最小值
// res[2] 最大值
// res[3] 总和
//并不是左子树的最小值一定是以这个节点为根的子树的最小,当左子树不存在的时候,当前根为该子树的最小值,同理,最大值也是,当右子树不存在时,根为最大。
//总是在想些乱七八糟的我。。。
int* traverse(TreeNode* root){
if(root == nullptr){
return new int[]{
1,INT_MAX,INT_MIN,0
};
}
int* left = traverse(root->left);
int* right = traverse(root->right);
//判断左右子树是否同时是BST,并且以该节点为根的子树是否是BST
if(left[0]==1 & left[2] < root->val & right[0]==1 & right[1] > root->val){
maxSum = max(maxSum,right[3] + left[3]+root->val);
return new int[]{
1, min(left[1],root->val) , max(right[2],root->val),right[3] + left[3]+root->val
};
}else{
return new int[]{
0,0,0,0
};
}
return new int[]{
0
};
}
};
参考东哥!