Maximum Sum BST in Binary Tree

hard tree bst dfs

Problem

Given the root of a binary tree, find the largest possible sum of node values among all subtrees that are valid Binary Search Trees. A subtree is any node together with all of its descendants. A single node counts as a BST. If no subtree is a BST with a positive sum, the answer is 0.

Inputroot = [4, 3, 8, 1, 5]
Output9
The subtree rooted at 3 is a BST (1 < 3 < 5) with sum 1 + 3 + 5 = 9. The whole tree is not a BST because 8 sits to the right of 4 yet the left subtree's max is 5 > 4.

def max_sum_bst(root):
    INF = float("inf")
    best = 0
    def dfs(node):
        nonlocal best
        if not node: return (True, 0, INF, -INF)
        lb, ls, lmin, lmax = dfs(node.left)
        rb, rs, rmin, rmax = dfs(node.right)
        if lb and rb and lmax < node.val < rmin:
            total = ls + rs + node.val
            best = max(best, total)
            return (True, total, min(lmin, node.val), max(rmax, node.val))
        return (False, 0, 0, 0)
    dfs(root)
    return best
function maxSumBST(root) {
  let best = 0;
  function dfs(node) {
    if (!node) return [true, 0, Infinity, -Infinity];
    const [lb, ls, lmin, lmax] = dfs(node.left);
    const [rb, rs, rmin, rmax] = dfs(node.right);
    if (lb && rb && lmax < node.val && node.val < rmin) {
      const total = ls + rs + node.val;
      best = Math.max(best, total);
      return [true, total, Math.min(lmin, node.val), Math.max(rmax, node.val)];
    }
    return [false, 0, 0, 0];
  }
  dfs(root);
  return best;
}
class Solution {
    int best = 0;
    public int maxSumBST(TreeNode root) { dfs(root); return best; }
    int[] dfs(TreeNode n) {
        if (n == null) return new int[]{ 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE };
        int[] L = dfs(n.left), R = dfs(n.right);
        if (L[0] == 1 && R[0] == 1 && L[3] < n.val && n.val < R[2]) {
            int total = L[1] + R[1] + n.val;
            best = Math.max(best, total);
            return new int[]{ 1, total, Math.min(L[2], n.val), Math.max(R[3], n.val) };
        }
        return new int[]{ 0, 0, 0, 0 };
    }
}
class Solution {
    int best = 0;
    tuple<bool,int,int,int> dfs(TreeNode* n) {
        if (!n) return {true, 0, INT_MAX, INT_MIN};
        auto [lb, ls, lmin, lmax] = dfs(n->left);
        auto [rb, rs, rmin, rmax] = dfs(n->right);
        if (lb && rb && lmax < n->val && n->val < rmin) {
            int total = ls + rs + n->val;
            best = max(best, total);
            return {true, total, min(lmin, n->val), max(rmax, n->val)};
        }
        return {false, 0, 0, 0};
    }
public:
    int maxSumBST(TreeNode* root) { dfs(root); return best; }
};
Time: O(n) Space: O(h)