力扣1373_二叉搜索子树的最大键值和

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

二叉搜索树的定义如下:

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

示例:
在这里插入图片描述
算法思想:
首先,二叉树题目核心–明确当前节点要做什么!
假如此时站在“1”这个节点,首先要判断它是不是一棵BST,如果它不是BST,直接就不用考虑计算键值和的事情了。
怎么知道它是不是BST呢?

  1. 先看它的两个孩子是不是BST,如果有个娃不是BST,那么它一定也不是BST
  2. 再看把“1”这个节点加入以后,整个树是不是BST("1"应该比它的左子树的最大节点还大,并且比右子树的最小节点还小)

知道它是BST后,我们再计算整个树的键值。
这样的一个思路,是不是和后序遍历一模一样呢,都是先遍历左右子节点,然后再处理根节点,也就确定了大致代码框架。

void traverse(TreeNode root) {
        traverse(root.left);
        traverse(root.right);

        //如果左右是BST
        
        //如果根节点加入还是BST

        //计算键值
    }

这里的难点在于判断左右是否BST,如果使用递归运算,那么时间复杂度将会非常的高,这里会存在大量的重复子问题,我们可以使用动态规划的备忘录剪枝,同时记录下一棵树的状态(是否BST),最大最小值,所有树的键值和。
使用什么数据结构能同时记录这些呢?当然是数组了,这里我们定义一个包含四个元素的数组,分别表示该树的状态(是否是BST),该树的最小值,该树的最大值,以及该树所有键值和,时间复杂度一下子就变为O(n),只需遍历一遍树就能得到解了。

代码实现:

int maxSum = 0;
    public int maxSumBST(TreeNode root) {
        traverse(root);
        return maxSum;
    }

    //返回一个大小为4的数组 int[]{isBST, min, max, sum}
    int[] traverse(TreeNode root) {

        //如果是空节点
        if(root == null) {
            return new int[]{1, Integer.MAX_VALUE, Integer.MIN_VALUE, 0};
        }

        //左右子树遍历
        int[] left = traverse(root.left);
        int[] right = traverse(root.right);

        //对根节点的处理
        int[] res = new int[4];
        if(left[0] == 1 && right[0] == 1 && root.val > left[2] && root.val < right[1]){
            //如果以root为起点的树符合BST定义
            res[0] = 1;
            res[1] = Math.min(left[1], root.val);
            res[2] = Math.max(right[2], root.val);
            res[3] = left[3] + right[3] + root.val;
            maxSum = Math.maxSum(maxSum, res[3]);
        } else {
            //如果不符合BST定义,只需要设置一个标志位就可以了
            res[0] == 0;
        }

        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值