题目描述:
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3] 输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7
解题思路:
·解这道题,只需要先找到最大深度的叶子节点,再找到判断其是否是位于最左边,使用递归法就可以轻松解决
·也可以使用迭代法,也就是层序遍历,使用层序遍历十分的简单,一层层的遍历,找到最深一层的第一个元素即可
递归法:
class Solution {
public:
int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root,int depth){
if(root->left == NULL && root->right == NULL){
if(depth > maxDepth){
maxDepth = depth;
result = root->val;
}
}
if(root->left){
depth++;
traversal(root->left,depth);
depth--;
}
if(root->right){
depth++;
traversal(root->right,depth);
depth--;
}
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
迭代法:
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue que;
if(root != NULL) 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;
}
};
总结:
这道题可以说是结合之前我们学习二叉树的大部分知识点
1.使用递归法求深度的写法2.在递归中使用回溯3.层次遍历法
题目描述:
给你二叉树的根节点 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 解释:由于树是空的,所以不存在根节点到叶子节点的路径。
解题思路:
·看题就知道肯定要使用递归法进行求解,如果使用迭代法,那就把简答问太过复杂化了
·有很多同学可能会让遍历过的叶子节点相加再和count进行对比,若相等则正确,不相等则不正确,但是可以使用逆向思维,使用count对遍历的叶子节点进行相减,这样会更方便以及更易理解
代码如下:
class Solution {
private:
bool tarversal(TreeNode* cur,int count){
//判断是否找到正确的路径,需要注意,这句话一定要在前,若第二段判断在前则会返回false
if(!cur->left && !cur->right && count == 0) return true;
if(!cur->left && !cur->right) return false;//判断是否是叶子节点
if(cur->left){//回溯
count -= cur->left->val;
if(tarversal(cur->left,count)) return true;
count += cur->left->val;
}
if(cur->right){//回溯
count -= cur->right->val;
if(tarversal(cur->right,count)) return true;
count += cur->right->val;
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
return tarversal(root,targetSum-root->val);
}
};
总结:这是一道很经典的使用递归与回溯的题目,代码中的回溯过程十分的清晰,如果看代码不能很清晰的理解,可以尝试画图进行理解
题目描述:
给你二叉树的根节点 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 输出:[]
解题思路:
·与前一题的解题思路是一样的,只是多了放在数组中
代码如下:
class Solution {
public:
vector> result;
vector path;
void traversal(TreeNode* cur,int count){
if(!cur->left && !cur->right && count == 0){
result.push_back(path);//找到叶子节点,将path放入result数组中
}
if(cur->left){
path.push_back(cur->left->val);//将左结点的值放入path中
count -= cur->left->val;
traversal(cur->left,count);
count += cur->left->val;//回溯
path.pop_back();// 取出元素
}
if(cur->right){//同理
path.push_back(cur->right->val);
count -= cur->right->val;
traversal(cur->right,count);
count += cur->right->val;
path.pop_back();
}
}
vector> pathSum(TreeNode* root, int targetSum) {
if(root == NULL) return result;
path.push_back(root->val);
traversal(root,targetSum-root->val);
return result;
}
};
总结:思想都是一样的使用递归与回溯进行求解,本题多了一步加入数组的步骤