程序员代码面试指南 3.7:找到二叉树中的最大搜索二叉子树

找到二叉树中的最大搜索二叉子树

https://www.nowcoder.com/practice/380d49d7f99242709ab4b91c36bf2acc

1、思路

  • 需要求出以每一个节点为头节点的子树的最大搜索二叉子树。对于每一个节点,我们用一个结构体ReturnType来保存该节点的四种信息:
    1、maxBSTHead 该子树中最大二叉搜索树的头节点;
    2、maxBSTSize 该子树中最大二叉搜索树的节点个数;
    3、min 该子树中最小节点值;
    4、max 该子树中最大节点值;

  • 以节点 root 为头节点的子树中,最大搜索二叉子树只可能有三种情况:
    1、最大搜索二叉子树是root左子树中的最大搜索二叉子树,即答案来自左子树;
    2、最大搜索二叉子树是root右子树中的最大搜索二叉子树,即答案来自右子树;
    3、最大搜索二叉子树是以root为头节点的子树,即答案来自root子树;

  • 先收集左子树信息,然后是右子树信息,最后在头节点做信息整合。由于是后序遍历,故时间复杂度为

2、代码

#include 
#include 

using namespace std;

struct TreeNode         //二叉树节点
{
    int val;
    TreeNode *left, *right;

    TreeNode(int _val) : val(_val), left(nullptr), right(nullptr) {}
};

struct ReturnType       //节点信息
{
    TreeNode *maxBSTHead;
    int maxBSTSize;
    int min;
    int max;

    ReturnType(TreeNode *_maxBSTHead, int _maxBSTSize, int _min, int _max) : 
                maxBSTHead(_maxBSTHead), maxBSTSize(_maxBSTSize), min(_min), max(_max) {}
};

void createTree(TreeNode *root, int &n)         //建树
{
    if (n == 0) return;

    int rootVal, leftVal, rightVal;
    cin >> rootVal >> leftVal >> rightVal;

    root->val = rootVal;
    if (leftVal != 0)
    {
        root->left = new TreeNode(leftVal);
        createTree(root->left, -- n);
    }
    if (rightVal != 0)
    {
        root->right = new TreeNode(rightVal);
        createTree(root->right, -- n);
    }
}

ReturnType* process(TreeNode *root)
{
    if (root == nullptr)                        //处理空节点
    {
        return new ReturnType(nullptr, 0, INT_MAX, INT_MIN);
    }

    ReturnType *leftData = process(root->left); //取得左右子树节点的信息
    ReturnType *rightData = process(root->right);

    //更新四种信息值
    int _min = min(root->val, min(leftData->min, rightData->min));
    int _max = max(root->val, max(leftData->max, rightData->max));
    int _maxBSTSize = max(leftData->maxBSTSize, rightData->maxBSTSize);
    TreeNode *_maxBSTHead = leftData->maxBSTSize >= rightData->maxBSTSize ? 
                            leftData->maxBSTHead : rightData->maxBSTHead;

    //特判以当前节点 root 为头节点的二叉树是否为二叉搜索树
    if (leftData->maxBSTHead == root->left && rightData->maxBSTHead == root->right 
        && root->val > leftData->max && root->val min)
    {
        _maxBSTSize = leftData->maxBSTSize + rightData->maxBSTSize + 1;
        _maxBSTHead = root;
    }

    return new ReturnType(_maxBSTHead, _maxBSTSize, _min, _max);
}

int main()
{
    int n, rootVal;
    cin >> n >> rootVal;

    TreeNode *root = new TreeNode(0);
    createTree(root, n);

    ReturnType *res = process(root);
    cout maxBSTSize << endl;

    return 0;
}

主要是为左程云的《程序员代码面试指南》这本书改写C++版的题解。

全部评论

相关推荐

09-24 18:30
已编辑
长春工业大学 产品经理
小肥罗:HR就是好人的缩写哈哈哈哈
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务