扯闲话时间。。。很长一段时间没有刷题了,因为工作做得一团糟,惨遭领导怒批,心理压力大得一批导致工作时间特别长又没产出,所以刷题就搁置了。。。
(小声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;
}
};
今天的分享就到这了,希望后面工作顺利。
来源:oschina
链接:https://my.oschina.net/u/4399698/blog/3640110