[98]验证二叉搜索树&[105]从前序与中序遍历序列构造二叉树
Posted left4back
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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; } };
今天的分享就到这了,希望后面工作顺利。
以上是关于[98]验证二叉搜索树&[105]从前序与中序遍历序列构造二叉树的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] 树 - 从前序与中序遍历序列构造二叉树, leetcode 105