给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3] 输出: 1
思路:这里找左下角的值,要满足两个条件,一是最底层,二是最左边。
解决:采用层次遍历,最后一层的第一个数就是要找的数。
代码:
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if(root!=NULL) que.push(root);
int n;//每层的结果
while(!que.empty()){
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* t=que.front();
que.pop();
if(i==0) n=t->val;//每层最左边的
if(t->left) que.push(t->left);
if(t->right) que.push(t->right);
}
}
return n;
}
};
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] 输出:[3,9,20,null,null,15,7]
思路:其实就是用代码模拟手动建树过程,一步一步还原手动步骤。
解决:分步骤解答:①判断数组为空;②利用后序数组最后元素分割中序数组,分为中序左数组和中序右数组;③再利用中序左数组和中序右数组分割后序数组,分为后序左数组和后序右数组;④递归步骤②。
注意:这里每次切割完中序数组后都要,舍去后序数组最后一个元素;中序分割和后序分割的区别,中序分割需要剔除后序数组最后元素,后序分割则不需要,根据中序左数组和中序右数组分割就行。
代码:
class Solution {
private:
TreeNode* traversal (vector<int>& inorder, vector<int>& postorder){
if(postorder.size()==0) return NULL;//第一步判空
//第二步找到后序数组最后元素
int rootg =postorder[postorder.size()-1];
TreeNode* root=new TreeNode(rootg);//该节点作为父亲节点
if(postorder.size()==1) return root;//最后遍历如果后序数组为就一个,说明是叶子节点,直接返回
//第三步分割数组
//先找到分割位置
int n;
for(n=0;n<inorder.size();n++){
if(inorder[n]==rootg) break;//记录分割位置
}
//通过分割位置分割中序数组
vector<int> leftinorder(inorder.begin(),inorder.begin()+n);//中序左数组
vector<int> rightinorder(inorder.begin()+n+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);
}
};
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]
思路:这里和上题类似,用前序和中序确定二叉树,前序是从前序数组第一个元素分割。
解决:同106
代码:
class Solution {
private:
TreeNode* traversal (vector<int>& inorder, vector<int>& preorder){
if(preorder.size()==0) return NULL;//第一步判空
//第二步找到前序数组最后元素
int rootg =preorder[0];
TreeNode* root=new TreeNode(rootg);//该节点作为父亲节点
if(preorder.size()==1) return root;//最后遍历如果前序数组为就一个,说明是叶子节点,直接返回
//第三步分割数组
//先找到分割位置
int n;
for(n=0;n<inorder.size();n++){
if(inorder[n]==rootg) break;//记录分割位置
}
//通过分割位置分割中序数组
vector<int> leftinorder(inorder.begin(),inorder.begin()+n);//中序左数组
vector<int> rightinorder(inorder.begin()+n+1,inorder.end());//中序右数组
//前序数组头部元素舍去
preorder.erase(preorder.begin());
//第四步分割前序数组
vector<int> leftpreorder(preorder.begin(),preorder.begin()+leftinorder.size());//前序左数组
vector<int> rightpreorder(preorder.begin()+leftinorder.size(),preorder.end());//前序右数组
//第五步链接左右子节点
root->left=traversal(leftinorder,leftpreorder);
root->right=traversal(rightinorder,rightpreorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (inorder.size() == 0 || preorder.size() == 0) return NULL;
return traversal(inorder, preorder);
}
};
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。
思路:从根节点开始依次搜索子节点,最后相加结果要等于总和,这里采用递归和回溯来判断是否接近于目标值。
解决:①首先,如果遇到叶子节点并且和为目标值,返回true;
②如果左右子节点都是叶节点但和不是目标值,返回false;
③判断左右子节点是否为空;
④先减去父节点的数再递归左右子节点;
⑤如果递归返回false,再加父节点数。
代码:
class Solution {
private:
bool traversal(TreeNode* root,int cur){
if(!root->left&&!root->right&&cur==0) return true;
if(!root->left&&!root->right) return false;
if(root->left){
cur-=root->left->val;
if(traversal(root->left,cur)) return true;
cur+=root->left->val;//回溯父节点
}
if(root->right){
cur-=root->right->val;
if(traversal(root->right,cur)) return true;
cur+=root->right->val;//回溯父节点
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (root == NULL) return false;
return traversal(root, targetSum - root->val);
}
};