目录
一、513.找树左下角的值
1.题目描述
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3] 输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7
2.解题思路
方法一:迭代法--层序遍历(广度优先搜索)
- 本题使用层序遍历还是比较容易解的,题目要返回最底层最左边的节点值,也就是层序遍历的最后一行的第一个元素。
方法二:递归法
ps:明确最底层的最左边的节点不一定是左孩子,也可能是右孩子!
- 最底层也就是深度最大的那一层,最左边节点的值也就是深度最大的一层的第一个节点值
- 因此,定义全局变量maxDepth用来记录最大深度,以及全局变量result。一旦遇到比最大深度还深的节点,就更新result值和maxDepth值。
3.代码实现(迭代法)
/**
* 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 findBottomLeftValue(TreeNode* root) {
//层序遍历
//广度优先搜索(迭代法)
queue<TreeNode*> que;
que.push(root);//题目所给条件:假设二叉树中至少有一个节点
int result;//记录结果,也就是最后一行的第一个数
while(!que.empty()){
int size = que.size();//记录每层有多少个节点
//不断更新每行的第一个数
result = que.front()->val;
for(int i = 0;i < size;i++){
//开始进行push、pop操作
TreeNode* node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;//返回结果--最后一行第一个数
}
};
4.代码实现(递归法)
/**
* 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;//全局变量,记录最大深度,遇到了比这个深度大的就更新result
int result;//全局变量,记录结果
//1.确定函数返回值和参数
void traversal(TreeNode* node,int depth){
//2.确定终止条件:如果是 叶子节点, 并且是最底层的的第一个节点 ,就更新result
if(node->left == NULL && node->left == NULL && depth > maxDepth){
//更新最大深度和result
maxDepth = depth;
result = node->val;
}
//单层递归逻辑
//这里体现回溯的思想
if(node->left){//左孩子不为空,才继续遍历左子树
//得先深度+1
depth++;
traversal(node->left,depth);
depth--;//回溯的思想
}//等价于 traversal(node->left , depth + 1);//这个实参实际上并没有对depth变量进行 + 1操作
if(node->right){
depth++;
traversal(node->right,depth);
depth--;
}
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,1);
return result;
}
};
二、112.路径总和
1.题目描述
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
输入:root = [1,2,3], targetSum = 5 输出:false 解释:树中存在两条根节点到叶子节点的路径: (1 --> 2): 和为 3 (1 --> 3): 和为 4 不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
输入:root = [], targetSum = 0 输出:false 解释:由于树是空的,所以不存在根节点到叶子节点的路径。
2.解题思路
递归思想:判断左右子树中是否存在 路径总和 = targetSum - root->val。如果有就返回true。
3.代码实现
/**
* 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:
//递归法
//1.确定递归参数和返回类型
bool traversal(TreeNode* node , int count){
//2.确定递归终止条件:如果是叶子节点,并且计数器count 为 0了,说明这条路径是我们想要的,直接return true
if(node->left == NULL && node->right == NULL && count == 0) return true;
if(node->left == NULL && node->right == NULL && count != 0) return false;
//3.确定单层递归逻辑:遍历左右子树,寻找符合条件的路径,如果找到了,返回上一层true
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
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
return traversal(root,targetSum - root->val);
}
};
三、113.路径总和 II
1.题目描述
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5 输出:[]
示例 3:
输入:root = [1,2], targetSum = 0 输出:[]
2.解题思路
和112.路径总和差不多,只不过这里要记录所有符合题目的路径,以及将路径的节点值保存下来。
3.代码实现
/**
* 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:
//1.确定递归函数参数和返回值
void traversal(TreeNode* node,vector<int>& path,vector<vector<int>>& result, int count){
//2.确定递归终止条件:遇到了叶子节点,并且路径总和等于目标总和
if(node->left == NULL && node->right == NULL && count == 0){
//符合题目要求,添加到结果集中
result.push_back(path);
}
//3.单层递归逻辑
if(node->left){
count -= node->left->val;
path.push_back(node->left->val);
traversal(node->left,path,result,count);
path.pop_back();
count += node->left->val;//回溯过程
}
if(node->right){
count -= node->right->val;
path.push_back(node->right->val);
traversal(node->right,path,result,count);
path.pop_back();
count += node->right->val;//回溯过程
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;//记录路径上的节点
vector<vector<int>> result;//结果集
if(root) {
path.push_back(root->val);
traversal(root,path,result,targetSum - root->val);
}
return result;
}
};