持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第34天,点击查看活动详情
题目链接:513. 找树左下角的值
题目描述
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
提示:
- 二叉树的节点个数的范围是
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
整理题意
给定一棵二叉树的根节点,找到这棵二叉树 最底层 最左边 节点的值。
题目提示该二叉树至少有一个节点。
解题思路分析
涉及到图和树的题目,一般都要遍历图或树。
- 由于题目要找最底层的元素,所以可以使用
BFS广度优先搜索 进行层序遍历。 - 考虑到最左边的元素,我们还可以使用
DFS深度优先搜索 进行遍历查找最左边的元素。
具体实现
BFS 广度优先搜索
- 从根节点开始层序遍历。
- 每次取出一层所有元素进行遍历,记录每层第一个元素即为最左边的元素,直至最后一层最左边的元素。
需要注意每次放入队列的顺序为先放左节点,再放右节点,这样可以保证每层第一个元素就为队列第一个元素。
DFS 深度优先搜索
- 从根节点开始遍历,遍历时需要一个变量来记录当前层数。
- 每层第一个遍历到的元素就为最左边的元素。
- 记录当前遍历的最大层数,当最大层数增加时,记录当前元素,因为此时为最大层数的第一个元素,也就是最左边的元素。
需要注意的是每次先遍历左子树再遍历右子树,这样可以保证当最大层数发生变化时,所遍历到的元素为当前层最左边的元素。
复杂度分析
- 时间复杂度:,其中
n是二叉树的节点数目。需要遍历n个节点。 - 空间复杂度:,如果二叉树是满完全二叉树,那么
BFS广度优先搜索队列que最多保存 个节点。DFS深度优先搜索递归栈需要占用 的空间。
代码实现
BFS 广度优先搜索
/**
* 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;
while(que.size()) que.pop();
que.push(root);
int ans = root->val;
//层序遍历
while(que.size()){
int n = que.size();
//flag 记录每层是否已经记录第一个元素
int flag = 1;
for(int i = 0; i < n; i++){
TreeNode* now = que.front();
que.pop();
//记录每层第一个元素
if(flag){
flag = 0;
ans = now->val;
}
//压入下一层元素
if(now->left != nullptr) que.push(now->left);
if(now->right != nullptr) que.push(now->right);
}
}
return ans;
}
};
DFS 深度优先搜索
/**
* 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 {
private:
//ans记录最底层最左边的元素,m记录当前遍历的最大层数
int ans, m;
//遍历二叉树,同时维护当前树的深度
void dfs(TreeNode* now, int deep){
//当最大层数发生变化时记录最左边的元素
if(deep > m){
m = deep;
ans = now->val;
}
//遍历左右子树,注意先遍历左子树
if(now->left != nullptr) dfs(now->left, deep + 1);
if(now->right != nullptr) dfs(now->right, deep + 1);
}
public:
int findBottomLeftValue(TreeNode* root) {
//初始化最大层数和最左边的节点值
m = 0;
ans = root->val;
dfs(root, 0);
return ans;
}
};
总结
- 涉及图和树的题目往往需要遍历图和树,涉及遍历问题,通常需要考虑广度优先搜索和深度优先搜索。
- 需要注意遍历顺序,由于该题求的时最左边的元素节点,所以先遍历左子树再遍历右子树。
- 测试结果:
结束语
人生犹如走山路,可能会历经高峰,也会落入低谷。想要冲出低谷,就要学会调整心态、沉淀自己。好的心态,是面对风雨,迎难而上;是身在低谷,不轻言放弃。拥有好的心态,我们才能在遭遇挫折时笑着面对。