携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情
题目描述
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
提示:
- 二叉树的节点个数的范围是
[1,104] -231 <= Node.val <= 231 - 1
解题思路——BFS
题目要求找树最下角的值,那么左下角是什么意思呢?
从示例中我们可以知道,不管树的层级有多深,左下角就是最后一层最左边的那个 叶子节点。
知道逻辑之后,马上就想到了层序遍历,在层序遍历中,使用一个二维数组将所有的遍历结果按层按节点顺序依次排放,那么二维数组最后一行的第一个元素,就是树的最底下最左侧,也就是左下角的值了。
题解——层序遍历
var findBottomLeftValue = function(root) {
if(root == null) return [];
let quote = [root], res = [];
while(quote.length) {
let lens = quote.length, temp = [];
for(let i=0; i<lens; ++i) {
let node = quote.shift();
temp.push(node.val);
node.left && quote.push(node.left);
node.right && quote.push(node.right);
}
res.push(temp);
}
let concatRes = res.slice(-1)[0][0]
return concatRes;
};
那么通过这种办法的话,是要开辟一个二维数组存储所有节点的值,但是我们其实记录其他节点的值是 没有意义 的,所以可以考虑优化一下。
既然我们需要的是最左侧的值,那么如果我们从右往左进行层序遍历,那么遍历到最后一个节点时,该节点就是左下角节点了。
题解——层序遍历优化
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var findBottomLeftValue = function(root) {
let queue = [root], res = 0;
while(queue.length) {
let node = queue.shift();
node.right && queue.push(node.right);
node.left && queue.push(node.left);
res = node.val;
}
return res;
};
解题思路——DFS
这道题有点像 [LeetCode199.二叉树的右视图](手摸手提桶跑路——LeetCode199. 二叉树的右视图 - 掘金 (juejin.cn)),只不过从多个右侧节点变成最后一层的左侧节点。所以解题思路上也可以参考一下那题。
我们优先遍历树的左节点。由于优先遍历左节点的缘故,因此对于每层来说,我们只要将该层的第一个遍历到的节点的值记录下来,就是该层的最左节点,那么一直记录到最后一层的第一个遍历到的节点,就是树的左下角的值了。
在这个过程中,除了最后一层外,所有的最左侧节点都是没有必要记录的,因此只需要一个变量去不断的更新每个层级的最左侧节点的值就好了,这样到了最后一层时,该变量的值就是题目所求解。
题解
var findBottomLeftValue = function(root) {
let max = 0, res = 0;
const dfs = (root, depth) => {
if (root == null) return;
if (depth > max) {
max = depth;
res = root.val;
}
dfs(root.left, depth + 1);
dfs(root.right, depth + 1);
}
dfs(root, 1);
return res;
};