一、找树左下角的值
递归方法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxdepth=INT32_MIN;
int result;
void traversal(TreeNode*startnode,int depth){
if(startnode->left==nullptr&&startnode->right==nullptr){
if(depth>maxdepth){
result=startnode->val;
maxdepth=max(maxdepth,depth);
}
}
if(startnode->left){
depth++;
traversal(startnode->left,depth);
depth--;
}
if(startnode->right){
depth++;
traversal(startnode->right,depth);
depth--;
}
}
int findBottomLeftValue(TreeNode* root) {
if(root==nullptr)return 0;
traversal(root,0);
return result;
}
};
递归三部曲:第一步 返回值类型为空,参数需要传入每次开始的节点指针,和与已存最大深度比较的depth 第二步 确定终止条件为找到叶子节点,找到后需要变更最大深度,然后用result记录当前节点的值。第三步 确定单词循环操作,也就是加入左子树的遍历和右子树的遍历,遍历过程中,在遍历时让depth+1确认新遍历了一层,然后调用递归函数,调用完了以后要把depth-1,用于回溯。
在看视频讲解的时候,我看到弹幕上面提了一个很有意义的问题,就是这段代码中如何体现是最左侧的叶子节点。经过我的思考和视频讲解,我认为,首先是因为maxdepth这个变量的存在,控制了同一层的节点之间比较,然后因为先遍历左侧,然后遍历右侧,这使得在同一层的情况下,先记录的节点值一定是左侧节点的值。如果先右后左,最后求的就是右下角的值了,经过更改调试实验发现确实如此。
二、路径之和
递归方法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool pathsum(TreeNode*root,int count){
if(root->left==nullptr&&root->right==nullptr&&count==0)return true;
if(root->left==nullptr&&root->right==nullptr&&count!=0)return false;
if(root->left){
count-=root->left->val;
if(pathsum(root->left,count))return true;
count+=root->left->val;
}
if(root->right){
count-=root->right->val;
if(pathsum(root->right,count))return true;
count+=root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==nullptr)return false;
return pathsum(root,targetSum-root->val);
}
};
第一步 确定返回值类型为bool 传参传入start节点指针和target减去根节点的值(用于做自减操作)
第二步 确定终止条件为 遍历到叶子节点时,最后结果为0说明找到,最后结果不为0说明没找到。
第三步 单层循环逻辑为左遍历:每次减去左/右节点的数,然后判断其子树返回值是否为真,然后递归后回溯
三、通过中序后序遍历建立二叉树
切割数组的思路学到了,但是还是懵懵的,尤其是左闭右开这里。右开体现为,vector用迭代器赋值时,(begin(),begin+index)后面那个是取不到的,参考end()
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(postorder.size()==0||inorder.size()==0)return nullptr;
int rootvalue=postorder[postorder.size()-1];
TreeNode*root=new TreeNode(rootvalue);
if(postorder.size()==1)return root;
int delimiterIndex;
for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++){
if(inorder[delimiterIndex]==rootvalue)break;
}
vector<int>leftInorder(inorder.begin(),inorder.begin()+delimiterIndex);
vector<int>rightInorder(inorder.begin()+delimiterIndex+1,inorder.end());
postorder.resize(postorder.size()-1);
vector<int>leftpostorder(postorder.begin(),postorder.begin()+leftInorder.size());
vector<int>rightpostorder(postorder.begin()+leftInorder.size(),postorder.end());
root->left=buildTree(leftInorder,leftpostorder);
root->right=buildTree(rightInorder,rightpostorder);
return root;
}
};