1.题意分析:
这道题 力扣上的题意就是找到叶子节点最左边节点的值 当然这个最左边节点的值不一定是左孩子 也可能是右孩子 只要满足是最左边的孩子而且还得是叶子节点即可
很显然 这道题使用层序遍历会相对简单一点 当然使用递归法也可以 我这里先介绍层序遍历 再来介绍递归
2.代码实现
01-迭代法(层序遍历)
var findBottomLeftValue = function(root) {
// 先判断
if(root === null)return null
// 定义一个队列 来存储每一层的值
let queue = [];
// 定义一个变量用来存储每一层最左边节点的val值
let leftVal = null;
// 第一层肯定是根节点 所以要把根节点先放进queue中
queue.push(root);
while(queue.length){
let length = queue.length; // 先将每一层节点的个数记录下来
for(let i = 0; i < length;i++){
let node = queue.shift() // 将每一层的每一个节点都给记录下来
if(i === 0){
// 如果i == 0 说明此时的节点肯定就是每一层的最左侧的值
leftVal = node.val;
}
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
}
return leftVal;
};
02-递归实现
001-递归解释:其实对于这道题 前序遍历(中左右) 后序遍历(左右中) 中序(左中右)遍历都一样 只要满足左在右的前面就可以 而这三种遍历方式都满足 中序在本题当中其实是没有要求的
let findBottomLeftValue = function(root){
let maxDeep = 0; // 定义最大深度
let leftNode = null; // 最左侧的节点
// 递归第一步:确定递归的参数和返回值
let fscTree = function(node,currDeep){
// 递归第二步:判断终止条件
if(node.left === null && node.right === null){ // 说明是叶子节点
if(currDeep > maxDeep){ // 判断是否是最大深度
maxDeep = currDeep;
leftNode = node.val; // 将最左侧的节点并且还是叶子节点 给leftNode(我们需要返回的值)
}
}
// 单层递归的逻辑、
if(node.left){
currDeep++;
fscTree(node.left,currDeep)
currDeep-- // 左 这里其实用到了回溯 为返回到上一层 进行上一个节点的右子树的遍历
}
/* 以上代码也可以简写,只不过是把回溯隐藏了
node.left && fscTree(node.left,currDeep+1) */
if(node.right){
currDeep++;
fscTree(node.right,currDeep)
currDeep-- // 这里其实用到了回溯
} // 右
/* 或者简写为 node.right && fscTree(node.right,currDeep+1) */
// 没有“中” 因为 中 是一个空的 放在哪里都行 而且本题也没有对中 进行操作
}
fscTree(root,1)
return leftNode;
}
3.总结
总结:首先就是要理解好题意。题目要求的是找到二叉树左下角的值 也就是二叉树最后一层最左侧的节点的值 这个最左侧的不一定是左子树。还有就是在递归的时候 用到的回溯 也是值得注意的点。