两道使用后序遍历的二叉搜索树问题

这篇博客探讨了两个基于后序遍历的二叉搜索树(BST)问题:LeetCode 333题——求最大BST子树,以及1373题——寻找二叉搜索子树的最大键值和。通过对二叉树进行后序遍历,可以有效地解决这些问题,找到满足BST性质的子树及其最大键值和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode 333 最大BST子树

https://leetcode-cn.com/problems/largest-bst-subtree/

(https://www.nowcoder.com/questionTerminal/380d49d7f99242709ab4b91c36bf2acc)

#include <map>
#include <unordered_map>
#include <cstdio>
#include <vector>
using namespace std;
 
struct TreeNode
{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int v_): val(v_), left(nullptr), right(nullptr){};
};
 
int maxcount = 0;
 
using node = pair<pair<bool, int>, pair<int,int>>;
// {以root为根子树是否是二叉搜索树,二叉搜索树的节点数,二叉搜索树的最大值,二叉搜索树的最小值}
node helper(TreeNode* root)
{
    if(!root) return {{true, 0}, {INT32_MIN, INT32_MAX}};
    auto left = helper(root->left);
    auto right = helper(root->right);
    node ret = {{false, 0}, {0, 0}};
    if(left.first.first && right.first.first)
    {
        if(root->val > left.second.first && root->val < right.second.second)
        {
            ret.first.first = true;
            ret.first.second = 1 + left.first.second + right.first.second;
            ret.second.first = max(root->val, right.second.first);
            ret.second.second = min(root->val, left.second.second);
        }
    }
    if(ret.first.first) maxcount = max(maxcount, ret.first.second);
    return ret;
}
 
int main()
{
    unordered_map<int, TreeNode*> mp;
    int n, rootval;
    scanf("%d%d", &n, &rootval);
    TreeNode* root = new TreeNode(rootval);
    mp[rootval] = root;
    for (int i = 0; i < n; ++i)
    {
        int fa, lch, rch;
        scanf("%d%d%d", &fa, &lch, &rch);
        TreeNode* r = nullptr, *lc = nullptr, *rc = nullptr;
        if(!mp.count(fa))
        {
            r = new TreeNode(fa);
            mp[fa] = r;
        }
        else r = mp[fa];
        if(lch > 0)
        {
            if(!mp.count(lch))
            {
                lc = new TreeNode(lch);
                mp[lch] = lc;
            }
            else lc = mp[lch];
        }
        if(rch > 0)
        {
            if(!mp.count(rch))
            {
                rc = new TreeNode(rch);
                mp[rch] = rc;
            }
            else rc = mp[rch];
        }
        r->left = lc;
        r->right = rc;
    }
    helper(root);
    printf("%d\n", maxcount);
    return 0;
}

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

class Solution {
private:
    struct node
    {
        bool isBST;
        int keysum;
        int maxval;
        int minval;
        node():isBST(true), keysum(0), maxval(INT32_MIN), minval(INT32_MAX){};
        node(bool b_, int k_, int max_, int min_):isBST(b_), keysum(k_), maxval(max_), minval(min_){};
    };
    int maxsum = 0;
    node helper(TreeNode* root)
    {
        if(!root) return node();
        auto left = helper(root->left);
        auto right = helper(root->right);
        node ret = node(false, root->val, INT32_MAX, INT32_MIN);
        if(left.isBST && right.isBST)
        {
            if(root->val > left.maxval && root->val < right.minval)
            {
                ret.isBST = true;
                ret.keysum += left.keysum + right.keysum;
                ret.minval = min(root->val, left.minval);
                ret.maxval = max(root->val, right.maxval);
            }
        }
        if(ret.isBST) maxsum = max(maxsum, ret.keysum);
        return ret;
    }
public:
    int maxSumBST(TreeNode* root) {
        helper(root);
        return maxsum;
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值