1.

cpp
/**
* 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 diameterOfBinaryTree(TreeNode* root) {
int maxn=0;
dfs(root,maxn);
return maxn;
}
int dfs(TreeNode*node,int &maxn)
{
if(!node) return 0;
int left=dfs(node->left,maxn);
int right=dfs(node->right,maxn);
maxn=max(maxn,right+left);
return max(left,right)+1;
}
};
说人话,题目的要求是找出两个距离最远的点,这两个点之间的边有多少条就是答案;
还是老方法,先不断递归左右子节点,就是算最大的深度,从根节点开始递归,也有可能某个子节点的两边就是最大的,所以随时更新这个maxn;
二叉树直径详解:一边求高度,一边更新答案
这道题是二叉树递归里的进阶模板题,很多人会卡在一个点:
为什么在"求高度"的同时就能算出"直径"?
一、什么是二叉树直径
任意两个节点之间最长路径的长度(边数)
注意两点:
-
路径不一定经过根节点
-
计算的是"边数",不是节点数
二、核心思路(关键一句话)
👉 直径 = 左子树高度 + 右子树高度
也就是说:
-
经过某个节点的最长路径
= 左边最深 + 右边最深
三、代码在做什么
cpp
int diameterOfBinaryTree(TreeNode* root) {
int maxn = 0;
dfs(root, maxn);
return maxn;
}
用一个变量 maxn 记录全局最大直径
核心递归:
cpp
int dfs(TreeNode* node, int &maxn)
这个函数做了两件事:
-
返回当前节点的高度
-
顺便更新最大直径
四、递归拆解(重点)
cpp
if (!node) return 0;
空节点,高度为 0
cpp
int left = dfs(node->left, maxn);
int right = dfs(node->right, maxn);
分别求左右子树高度
maxn = max(maxn, left + right);
更新直径(关键)
因为:
当前节点的"最长路径" = 左高 + 右高
return max(left, right) + 1;
返回当前节点高度
五、举个例子
1
/ \
2 3
/ \
4 5
分析:
-
节点 2:左高=1,右高=1 → 路径=2
-
节点 1:左高=2,右高=1 → 路径=3(最大)
最终答案 = 3
六、为什么这样是对的
很多人误区在这里:
"直径不是路径吗,为什么用高度算?"
关键理解:
-
高度 = 从当前节点往下的最长路径
-
两边拼起来 = 经过当前节点的最长路径
所以:
每个节点都尝试当"拐点"
全局取最大即可
七、时间和空间复杂度
时间复杂度:
O(n),每个节点访问一次
空间复杂度:
O(h),递归深度
八、这一题的本质
后序遍历 + 在回溯时做额外计算
你可以这样记:
-
前序:处理当前节点
-
中序:处理中间
-
后序:用子树信息更新当前
这题就是典型后序:
先拿左右结果 → 再更新答案
2.

cpp
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>>res;
if(root==NULL)
{
return res;
}
queue<TreeNode*>q;
q.push(root);
while(!q.empty())
{
int n=q.size();
vector<int>ans;
for(int i=0;i<n;i++)
{
TreeNode*node=q.front();
q.pop();
ans.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
res.push_back(ans);
}
return res;
}
};
二叉树层序遍历详解(BFS模板,一题打通)
这道题是二叉树里必须掌握的广度优先搜索(BFS)模板题,基本属于面试必考。
你这份代码已经是标准答案级别了,我们把它彻底拆清楚,让你以后看到类似题直接秒。
一、什么是层序遍历
按"层"一层一层往下遍历
顺序是:
从上到下,从左到右
例如:
3
/ \
9 20
/ \
15 7
输出是:
[
[3],
[9,20],
[15,7]
]
二、核心思想(BFS)
用队列(queue)实现
流程就是:
-
根节点入队
-
每次取出一层
-
把下一层节点加入队列
三、你的代码在做什么
queue<TreeNode*> q;
q.push(root);
初始化队列,从根节点开始
关键点:如何区分"每一层"
int n = q.size();
当前队列里的所有节点,就是这一层的节点数量
遍历这一层
for (int i = 0; i < n; i++)
固定循环 n 次,只处理当前层
取节点 + 加入结果
TreeNode* node = q.front();
q.pop();
ans.push_back(node->val);
把下一层加入队列
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
下一轮 while 就会处理这一层
收集每一层结果
res.push_back(ans);
四、完整执行流程(关键理解)
以这棵树为例:
1
/ \
2 3
过程:
第一轮:
队列:[1]
→ 取出 1
→ 加入 [2,3]
结果:[ [1] ]
第二轮:
队列:[2,3]
→ 取出 2,3
→ 加入子节点
结果:[ [1], [2,3] ]
五、时间和空间复杂度
时间复杂度:
O(n),每个节点访问一次
空间复杂度:
O(n),队列最多存一层节点
六、这一题的本质模板
BFS + 分层处理
以后遇到这些题,都是这一套:
-
二叉树右视图
-
每层平均值
-
锯齿形遍历
-
最短路径(图论)
本质都是:
while(队列不空)
取当前层大小
遍历这一层
加入下一层