Leetcode - 1373. 二叉搜索子树的最大键值和

124 阅读1分钟

1.题目简述

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

示例

输入:root = [1,2,3,1,5,2,5,null,null,null,null,null,null,4,6]

输出:20

解释:键值为 3 的子树是和最大的二叉搜索树

未命名绘图.drawio.png 详情请查看 LeetCode 官网:1373. 二叉搜索子树的最大键值和 - 力扣(LeetCode)

2.方法

通过 后序遍历遍历二叉树。遍历到某一节点时,进行如下的判断:

  • 判断其左子树和右子树是否为二叉搜索树
  • 判断节点值是否大于左子树最大值
  • 判断节点值是否小于右子树的最小值

当都符合条件时,则说明以该节点为根的树是二叉搜索树。

为了实现以上的目标,可以定义一个子树结构(SubTree):

  • boolean isBST:是否为二叉搜索树
  • int maxValue:当前子树的最大节点值
  • int minValue:当前子树的最小节点值
  • int sumValue:当前子树的节点值和
class Solution {

    final int INF = 40002;
    int ans;

    public int maxSumBST(TreeNode root) {
        if(root == null) return 0;
        ans = 0;
        dfs(root);
        return ans;
    }

    SubTree dfs(TreeNode root){
        if(root == null){
            // 节点为空时,返回一个二叉搜索树的子树
            return new SubTree(true,-INF,INF,0);
        }

        SubTree left = dfs(root.left);
        SubTree right = dfs(root.right);
        
        // 进行文中所说的判断
        if(left.isBST && right.isBST && root.val>left.maxValue && root.val<right.minValue){
            int sum = left.sumValue + right.sumValue + root.val;
            ans = Math.max(ans,sum);
            return new SubTree(true,Math.max(root.val,right.maxValue),Math.min(root.val,left.minValue),sum);
        }else{
            return new SubTree(false,0,0,0);
        }
    }
    
    class SubTree{
        boolean isBST;
        int maxValue;
        int minValue;
        int sumValue;
        public SubTree(boolean isBST,int maxValue,int minValue,int sumValue){
            this.isBST = isBST;
            this.maxValue = maxValue;
            this.minValue = minValue;
            this.sumValue = sumValue;
        }
    }
}