一、找树左下角的值
题目链接/文章讲解/视频讲解: 代码随想录
1.可以将前序遍历的中的操作放到左和右中
2.注意是大于号:depth>maxdepth
一次递归一次回溯
代码:
class Solution {
public:
int maxDepth = INT_MIN;
void Traversal(TreeNode* root,int &depth,int &result)
{ //说明到叶子节点了
if(root->left==nullptr&&root->right==nullptr)
{
if(depth>maxDepth)//是要大于,这样才会使最左边的
{
result=root->val;
maxDepth=depth;
}
}
if(root->left)
{
depth++;
Traversal(root->left,depth,result);
depth--;
}
if(root->right)
{
depth++;
Traversal(root->right,depth,result);
depth--;
}
return;
}
int findBottomLeftValue(TreeNode* root) {
int depth=-1;
int result=0;
Traversal(root,depth,result);
return result;
}
};
二、路径之和
题目链接/文章讲解/视频讲解: 代码随想录
1.做过 257. 二叉树的所有路径,这题并不难,我采用的还是前序遍历
2.可以做累减,比累加简单
3.可以将前序遍历的中的操作放到左和右中
代码:
class Solution {
public:
bool result=false;
bool Traversal(TreeNode* root, int targetSum,int &res)
{
res+=root->val;
if(root->left==nullptr&&root->right==nullptr)
{
if(res==targetSum)
return true;
else
return false;
}
if(root->left)
{
result=Traversal(root->left,targetSum,res);
res-=root->left->val;
}
if(result==true) return true;//提前返回结果
if(root->right)
{
result=Traversal(root->right,targetSum,res);
res-=root->right->val;
}
return result;
}
bool hasPathSum(TreeNode* root, int targetSum) {
int res=0;
if(!root) return false;
return Traversal(root,targetSum,res);
}
};
可以将前序遍历的中的操作放到左和右中
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;
三、 从中序与后序遍历序列构造二叉树
题目链接/文章讲解/视频讲解: 代码随想录
1.前提:不可以有重复的元素,这样切割的时候答案不唯一。
2.利用中序和后序的特性解决这个问题
说到一层一层切割,就应该想到了递归。
来看一下一共分几步:
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
代码:
class Solution {
private:
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;
}
// 中序数组分为左半边,右半边
// 注意vector利用另一个vector初始化,是左闭右开
//vector<int> a;
//a=vector<int>(nums.begin(), nums.end());
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 = traversal(leftInorder, leftPostorder);
root->right = traversal(rightInorder, rightPostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
return traversal(inorder, postorder);
}
};