• Leetcode刷题1373. 二叉搜索子树的最大键值和


    给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。

    二叉搜索树的定义如下:

    任意节点的左子树中的键值都 小于 此节点的键值。
    任意节点的右子树中的键值都 大于 此节点的键值。
    任意节点的左子树和右子树都是二叉搜索树。
     

    示例 1:

    输入:root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
    输出:20
    解释:键值为 3 的子树是和最大的二叉搜索树。


    示例 2:

    输入:root = [4,3,null,1,2]
    输出:2
    解释:键值为 2 的单节点子树是和最大的二叉搜索树。


    示例 3:

    输入:root = [-4,-2,-5]
    输出:0
    解释:所有节点键值都为负数,和最大的二叉搜索树为空。


    示例 4:

    输入:root = [2,1,3]
    输出:6


    示例 5:

    输入:root = [5,4,8,3,null,6,3]
    输出:7
     

    提示:

    每棵树有 1 到 40000 个节点。
    每个节点的键值在 [-4 * 10^4 , 4 * 10^4] 之间。

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/maximum-sum-bst-in-binary-tree
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    感谢 labuladong的详细解法美团面试官:你对二叉树后续遍历一无所知失火的夏天大佬的详细解法深度优先搜索 最优解一定在BST的子树中 8ms

    1. class Solution {
    2. int maxSum = 0;
    3. public int maxSumBST(TreeNode root) {
    4. // return maxSumBSTI(root);
    5. //方法二:DFS遍历
    6. int[] res = {0};
    7. maxSumBSTII(root, res);
    8. return res[0];
    9. }
    10. private void maxSumBSTII(TreeNode root, int[] res) {
    11. if (root == null) {
    12. return;
    13. }
    14. //如果当前节点的二叉树是BST,直接求和
    15. if (isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE)) {
    16. //是二叉搜索树,求和,最大值一定在子节点的求和过程中
    17. sumNodeVal(root, res);
    18. return;
    19. }
    20. //不是BST,递归左右子树
    21. maxSumBSTII(root.left, res);
    22. maxSumBSTII(root.right,res);
    23. }
    24. private int sumNodeVal(TreeNode root, int[] res) {
    25. if (root == null) {
    26. return 0;
    27. }
    28. //二叉搜索树节点和的最大值,一定在子节点中会出现
    29. int sum = root.val + sumNodeVal(root.left, res) + sumNodeVal(root.right, res);
    30. res[0] = Math.max(res[0], sum);
    31. return sum;
    32. }
    33. private boolean isBST(TreeNode root, int minValue, int maxValue) {
    34. if (root == null) {
    35. return true;
    36. }
    37. return minValue < root.val && root.val < maxValue && isBST(root.left, minValue, root.val) && isBST(root.right, root.val, maxValue);
    38. }
    39. //方法一:递归,时间和空间复杂度O(N)
    40. //思考当前节点需要做什么?
    41. //1.当前节点为根的二叉树是否是BST?左孩子是否是BST,右孩子是否是BST?
    42. //2.如果左右都是BST,需要判断加上自己是否是BST,怎么判断?当前节点是是否大于左孩子最小值,小于右孩子最大值
    43. //3.当前节点为根的二叉树所有节点值之和
    44. private int maxSumBSTI(TreeNode root) {
    45. if (root == null) {
    46. return 0;
    47. }
    48. traverse(root);
    49. return maxSum;
    50. }
    51. //定义4个长度的int数组,int[0]表示以root为根的二叉树是否为二叉搜索树
    52. //int[1]表示以root为根的二叉树所有节点最小值,int[2]表示以root为根的二叉树所有节点最大值
    53. //int[3]表示以root为根的二叉树节点值之和
    54. private int[] traverse(TreeNode root) {
    55. if (root == null) {
    56. return new int[]{1, Integer.MAX_VALUE, Integer.MIN_VALUE, 0};
    57. }
    58. int[] res = new int[4];
    59. //当前节点要做的事情需要通过左右子树的计算结果推导出来,使用后序遍历
    60. int[] left = traverse(root.left);
    61. int[] right = traverse(root.right);
    62. if (root.val < right[1] && root.val > left[2] && left[0] == 1 && right[0] == 1) {
    63. res[0] = 1;
    64. // if (left[1] != Integer.MAX_VALUE) {
    65. // res[1] = left[1];
    66. // } else {
    67. // res[1] = root.val;
    68. // }
    69. // if (right[2] != Integer.MIN_VALUE) {
    70. // res[2] = right[2];
    71. // } else {
    72. // res[2] = root.val;
    73. // }
    74. //这里是为了避免当左子树为空或者右子树为空时
    75. //直接取左子树最小值时取到Integer.MAX_VALUE,直接取右子树最大值时取到Integer.MIN_VALUE
    76. res[1] = Math.min(root.val, left[1]);
    77. res[2] = Math.max(root.val, right[2]);
    78. res[3] = root.val + left[3] + right[3];
    79. maxSum = Math.max(res[3], maxSum);
    80. }
    81. return res;
    82. }
    83. }

  • 相关阅读:
    数字孪生助力智慧城市、楼宇、园区场景数字化系统建设
    Leetcode刷题详解——点名
    G1D10-APT论文(综述应用部分)
    idea显示maven或者gradle无法从仓库获取到项目中的jar包,jar包所在仓库无法访问解决方法,百试百灵
    我终于读懂了设计模式的七大原则。。。
    记一次springboot项目结合arthas排查ClassNotFoundException问题
    【超详细断点级别讲解 SpringSecurity】项目实战:用户认证、用户授权
    2024年最新最全最好用的10大开源项目管理软件
    实习经历复盘
    搜索引擎中的相关性模型
  • 原文地址:https://blog.csdn.net/Bonbon_wen/article/details/127591592