513.找树左下角的值
首先还是递归三部曲,在选择参数这里每次都会犹豫,不过本题选择了直接定义全局变量,记录深度:
int result;
int maxDepth=INT_MIN;
同时精巧地在最下面一层先检测左边节点,并将最深层的左侧值赋予,再一次检测到最深层的元素时,一定不是最左值,不再赋值,同时每次进入跳出递归时不忘更改depth值实现回溯。
if(depth>maxDepth){
maxDepth=depth;
result=root->val;
}
if(root->left){
depth++;
getDepth(root->left,depth);
depth--;
}
if(root->right){
depth++;
getDepth(root->right,depth);
depth--;
}
112. 路径总和
本题最精髓的地方在于在确定路径存在时返回什么样的值告诉上一层,这也涉及到了讲解的内容
再来看返回值,递归函数什么时候需要返回值?什么时候不需要返回值?这里总结如下三点:
- 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况就是本文下半部分介绍的113.路径总和ii)
- 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 (这种情况我们在236. 二叉树的最近公共祖先 (opens new window)中介绍)
- 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(本题的情况)代码随想录 (programmercarl.com)
并在单层递归中判断返回值:
if(search(root->left,count))return true;
113. 路径总和ii
同样是含有回溯的二叉树递归,同时判断路径,不同的是这次加入了数组,即需要将路径塞入数组中,并返回数组,这与之前的一道返回数组字符串的题类似257. 二叉树的所有路径 - 力扣(LeetCode)
每次判断的代码:
if(root->left){
temp.push_back(root->left->val);
count-=root->left->val;
search(root->left,count);
count+=root->left->val;
temp.pop_back();
}
if(root->right){
temp.push_back(root->right->val);
count-=root->right->val;
search(root->right,count);
count+=root->right->val;
temp.pop_back();
}
106.从中序与后序遍历序列构造二叉树
本题最关键的就是要考虑清楚其中的数学关系:即根据中序数组的头节点元素作为根节点元素,并在后序数组中寻找根节点的值,同时将后序数组在根结点处跟为两段,一半为树左侧元素,一半为树右侧元素,并将中序数组同样的分为左右两枝的片段(大小与后序左右两枝等同)这样就实现了每一层的分割操作,再实现递归即可。
oot->left=traversal(leftIn,leftPost);
root->right=traversal(rightIn,rightPost);
105.从前序与中序遍历序列构造二叉树
与上一题同样的思路,但是答案用了数字表示数组分割的位置,而不是再对数组进行直接分割,但是我按照上一题的思路编写,却发生了错误:
class Solution { public: TreeNode* traversal(vector<int>&preorder,vector<int>& inorder){ int valueRoot=inorder[0]; TreeNode* root=new TreeNode(inorder[0]); if(preorder.size()==1)return root; int index; for(index=0;index<preorder.size()-1;index++){ if(preorder[index]==valueRoot)break; } vector<int>preLeft(preorder.begin(),preorder.begin()+index); vector<int>preright(preorder.begin()+index+1,preorder.end()); vector<int>inleft(inorder.begin()+1,inorder.begin()+1+preLeft.size()); vector<int>inright(inorder.begin()+1+preLeft.size(),inorder.end()); root->left=traversal(preLeft,inleft); root->right=traversal(preright,inright); return root; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { if(preorder.size()==0)return NULL; return traversal(preorder,inorder); } };
具体错误是最后输出的结果有问题,不知道不同的写法为什么会出错,感觉可能是分片没做好。