[98]验证二叉搜索树&[105]从前序与中序遍历序列构造二叉树

扯闲话时间。。。很长一段时间没有刷题了,因为工作做得一团糟,惨遭领导怒批,心理压力大得一批导致工作时间特别长又没产出,所以刷题就搁置了。。。

(小声BB)其实感觉领导有点刀子嘴豆腐心,一面说着“公司没义务从零培养新人,我自己也很久不带新人了”,一面又给我讲了好多基础知识。。。

好了,言归正传,今天分享两道题,同类型的,力扣(leetcode中国)给的标签都是深度优先搜索,但是我都没想出来怎么用深度优先,所以都采用了递归。

这里提一句,曾经有位前辈和我说实际工作中递归并不常用,因为递归长度过长的话,效率也会大打折扣。所以这两道题我会再想想如何不用递归解决。

第一道题是No.98验证二叉搜索树,递归的思路特别简单,递归地验证左子树所有节点<根节点<右子树所有节点,也就是中序遍历有序的是搜索二叉树。

代码如下,扯句闲话,递归代码是真的简洁好看(源代码是力扣上一位前辈贴在评论区里的)。

class Solution {
public:
    double last = -DBL_MAX;
    bool isValidBST(TreeNode* root) {
        if (!root) return true;
        if (isValidBST(root->left)) {
            if (last < root->val) {
                last = root->val;
                return isValidBST(root->right);
            }
        }
        return false;
    }
};

第二道题是No.105从前序与中序遍历序列构造二叉树。可以说这是一道经典老题了,递归的思路同样很直观,前序遍历的第一个点必是根节点,然后按照这个根节点的值找到中序遍历中根节点对应的索引值。得到这个索引值后就可以将前序遍历分为左子树的前序遍历、根节点、右子树的前序遍历;将中序遍历分为左子树的中序遍历、根节点、右子树的中序遍历。接下来就不用多说了8,递归就vans了。

代码如下,这是另一位老哥贴在评论区里的,至于我自己写的代码?为了偷懒不构造辅助函数,在树变得特别深的时候创造了大量 子vector导致StackOverflow。。。

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int len = preorder.size();
        return build(preorder,0,len-1,inorder,0,len-1);
    }
    TreeNode* build(vector<int>& pre,int ps,int pe,vector<int>& in,int is,int ie){
        TreeNode *p=NULL;
        if(ps<=pe){
            p = new TreeNode(pre[ps]);
            int index=is;
            for(;index<=ie;index++){
                if(in[index]==p->val) break;
            }
            int llen=index-is;
            int rlen=ie-index;
            p->left = build(pre,ps+1,ps+llen,in,is,index-1);
            p->right = build(pre,pe-rlen+1,pe,in,index+1,ie);
        }
        return p;
    }
};

今天的分享就到这了,希望后面工作顺利。

猜你喜欢

转载自www.cnblogs.com/left4back/p/10421240.html