找树左下角的值
题目链接/文章讲解/视频讲解: 代码随想录
解题思路
这里比较容易搞混的点就是:左下角的值是最深层最左侧的叶子节点,那其实三种遍历方式都是可以的,我们因为中节点不做处理,只需要去递归到左边的最底层,没有就去递归右节点的最底层即可
迭代法(比较简单,模版)
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
int result;
while(!que.empty())
{
int size = que.size();
for(int i=0;i<size;i++)
{
TreeNode* node = que.front();
que.pop();
if(i==0){
result = node->val;
}
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
递归法(含回溯)
回溯就是让这一层递归前后的值不变
class Solution {
public:
int result;
int maxDepth = INT32_MIN;
void travelSal(TreeNode* node , int depth)
{
if(node->left==nullptr && node->right==nullptr)
{
if(depth>maxDepth) //如果是更深层的叶子节点则记录,如果不是就不做处理
{
maxDepth = depth;
result = node->val;
}
}
//不是叶子节点,则先遍历左,再遍历右,体现了左下角
if(node->left) travelSal(node->left,depth+1);
if(node->right) travelSal(node->right,depth+1);
}
int findBottomLeftValue(TreeNode* root) {
travelSal(root,1);
return result;
}
};
路径总和
题目链接/文章讲解/视频讲解: 代码随想录
解题思路
这题还是比较简单的,我的思路使用中左右前序遍历,去寻找相加等于路径和的就可以,记得回溯
class Solution {
public:
bool findSum(TreeNode* node, int targetSum)
{
if(node==nullptr) return false;
if(node->left==nullptr && node->right == nullptr) //遇到叶子节点,就判断路径和是否达到
{
if(targetSum- node->val ==0) return true;
else return false;
}
if(node->left) {
targetSum-= node->val;
if(findSum(node->left,targetSum)) return true; //如果左孩子可以,收集信息返回父节点
targetSum+= node->val;
}
if(node->right){
targetSum -=node->val;
if(findSum(node->right,targetSum)) return true;
targetSum += node->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
return findSum(root,targetSum);
}
};
从中序与后序遍历序列构造二叉树
题目链接/文章讲解/视频讲解: 代码随想录
解题思路
后序遍历序列的最后一个元素一定是根节点,那么根据这个可以找到中序序列中和这个相等的索引下标,用去切割中序遍历序列,分为左区间和右区间,随后根据左区间和右区间再切割后序序列,然后递归左右区间即可·
切割中序比较简单,那切割后序呢?
我们只需要先用resize将最后一个元素舍弃后,用中序的左右区间的数量去切割即可,因为他们的数量必定是相同的。
注意:前序和中序也可以构造二叉树,但是前序和后序无法构造,因为不能将左右子树分开
class Solution {
public:
TreeNode* travelSal(vector<int>& inorder, vector<int>& postorder)
{
if(postorder.size()==0) return NULL;
int rootValue = postorder[postorder.size()-1]; //最后一个元素就是根节点
TreeNode* root = new TreeNode(rootValue);
if(postorder.size()==1) return root; //叶子节点,也是根节点,返回给上层
//第三步,去中序序列中找到元素索引
int index;
for( index=0;index<inorder.size();index++)
{
if(inorder[index]==rootValue)
break;
}
//切割中序左右(左闭右开),注意避开切割节点
vector<int> leftinorder(inorder.begin(),inorder.begin()+index);
vector<int> rightinorder(inorder.begin()+index+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 = travelSal(leftinorder,leftPostOrder);
root->right = travelSal(rightinorder,rightPostOrder);
return root; //构造完了返回节点给上面接收
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return travelSal(inorder,postorder);
}
};