代码随想录算法训练营第18天|513.找树左下角的值|112. 路径总和 113.路径总和ii|106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
找树左下角的值
本地递归偏难,反而迭代简单属于模板题, 两种方法掌握一下
题目链接/文章讲解/视频讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html
/**
* 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=INT_MIN;
int result;
void traversal(TreeNode *root,int depth)
{
if(root->left==NULL&&root->right==NULL)
{
if(maxdepth<depth)
{
maxdepth=depth;
result=root->val;
}
}
if(root->left)//左(必须先判断左的结点)
{
depth++;
traversal(root->left,depth);
depth--;//回溯
}
if(root->right)//右
{
depth++;
traversal(root->right,depth);
depth--;//回溯
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
路径总和
本题 又一次设计要回溯的过程,而且回溯的过程隐藏的还挺深,建议先看视频来理解
- 路径总和,和 113. 路径总和ii 一起做了。 优先掌握递归法。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0112.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C.html
- 路径总和
/**
* 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 {
private:
bool traversal(TreeNode* node,int count)
{
if(!node->left &&!node->right && count==0)
return true;
if(!node->left && !node->right)
return false;
if(node->left)
{
count-=node->left->val;
if(traversal(node->left,count))return true;
count+=node->left->val;
}
if(node->right)
{
count-=node->right->val;
if(traversal(node->right,count))return true;
count+=node->right->val;
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL)
return false;
return traversal(root,targetSum-root->val);
}
};
/*class Solution {
private:
bool traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回
if (cur->left) { // 左
count -= cur->left->val; // 递归,处理节点;
if (traversal(cur->left, count)) return true;
count += cur->left->val; // 回溯,撤销处理结果
}
if (cur->right) { // 右
count -= cur->right->val; // 递归,处理节点;
if (traversal(cur->right, count)) return true;
count += cur->right->val; // 回溯,撤销处理结果
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL) return false;
return traversal(root, sum);
}
};*/
总结
在打代码途中,我试了!node->left &&!node->right改为node->left!=NULL &&node->right!=NULL,结果是错的因为验证结果里有null
所以!=NULL跟null起了冲突,还有最后的必须先剪一个结点的值然后带入,不然不符合做题思想和报错。
从中序与后序遍历序列构造二叉树
本题算是比较难的二叉树题目了,大家先看视频来理解。 106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树 一起做,思路一样的
题目链接/文章讲解/视频讲解:https://programmercarl.com/0106.%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.html
106.从中序与后序遍历序列构造二叉树
/**
* 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* traversal(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;
// 切割中序数组
// 左闭右开区间:[0, delimiterIndex)
vector<int>leftinorder(inorder.begin(),inorder.begin()+index);
// [delimiterIndex + 1, end)因为要分割所以+1
vector<int>rightinorder(inorder.begin()+index+1,inorder.end());
// postorder 舍弃末尾元素
postorder.resize(postorder.size()-1);
// 切割后序数组
// 依然左闭右开,注意这里使用了左中序数组大小作为切割点
// [0, leftInorder.size)
vector<int>leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size());
// [leftInorder.size(), end)
vector<int>rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());
root->left=traversal(leftinorder,leftpostorder);
root->right=traversal(rightinorder,rightpostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0)
return NULL;
return traversal(inorder,postorder);
}
};