最大二叉搜索子树问题

来源:互联网 发布:mac os x摄像头软件 编辑:程序博客网 时间:2024/05/16 06:57


【题目】

有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.
给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。


【分析】

最大二叉搜索子树,我们只需要使用三个变量保存每个结点为根的子树的min,max,以及它对应的最大二叉搜索子树的结点数目。然后判断是否更新即可。

注意两点:(左半部分最大值用lmax表示,右半部分最小值用rmin表示,t表示当前根节点)

  1. 如果lmax < t->val < rmin,那么以该结点为根的子树更新为最大二叉搜索子树,最大二叉搜索子树的数目等于左数目+1(自己)+右数目。
  2. 如不满足1,那就找出左右数目最大的返回即可,继续寻找,并判断是否更新。

【代码】
class MaxSubtree {public:    TreeNode* getMax(TreeNode* root) {        assert(root != nullptr);        vector<int> res(3, 0);         return get_max_detail(root, res);    }private:    TreeNode* get_max_detail(TreeNode* t, vector<int>& res){        if(t == nullptr){ //res[0] means min, res[1] means max, res[2] means counter of BST tree node            res[0] = INT_MAX;            res[1] = INT_MIN;            res[2] = 0;            return nullptr;        }                int lmin = 0, lmax = 0, lcnt = 0;        TreeNode* lnode = get_max_detail(t->left, res);        lmin = res[0];        lmax = res[1];        lcnt = res[2];                   TreeNode* rnode = get_max_detail(t->right, res);                //don't do like (lnode==null && rnode==null) || (lmax<t->val && rmax>t->val)        //because the lnode or rnoe maybe not the child of the "t".        if((lnode == t->left && rnode == t->right)            && (lmax < t->val && res[0] > t->val)){    //update            res[0] = std::min(lmin, t->val);            res[1] = std::max(res[1], t->val);            res[2] = lcnt + res[2] + 1;            return t;        }                if(lcnt > res[2]){            //res[0] = lmin;    //this line deleted is also ok            //res[1] = lmax;   //this line deleted is also ok            res[2] = lcnt;            return lnode;        }        else            return rnode;    }};
这道题难点在叶子结点的情况,刚开始我处理方式是如图注释中那种情况,没有考虑到如果最大二叉搜索子树不是连续的,即最大二叉搜索子树在某个结点1断开,可能当时最大的二叉搜索子树是结点1的左孩子拥有的子树X(不包括结点1),继续向根部回溯后,出现另外一个右分支中的最大二叉搜索子树Y,它的根的父亲不是结点1,此时如果子树X的最大值 < t->val < 子树Y的最小值,这样新合成一个包括断点,以及中间可能多个不连续的点的新最大二叉搜索子树,这是错误的

所以,需要用(lnode==t->left && rnode==t->right && ...)作为判断条件。

值得注意的是,最后有两句话是可以去掉的。因为出现那种情况,等于出现了断层。以后只需要比较它们的数目,不关心它们的min和max了。

0 0
原创粉丝点击