对称二叉树
给你一个二叉树的根节点,判断它是否对称

输入: root = [1,2,2,3,4,4,3]
输出: true
思路分析
使用递归来解题,因为是求对称,所以判断的时候需要满足两个点,第一个点就是任意根节点的左子树等于右子树,具有相同的值。第二个点就是镜像对称。
具体可以使用递归函数,通过同步移动两个指针的方法来遍历这颗树,p指针和q指针一开始都指向这颗树的根,随后p左移的时候p右移,p右移的时候q左移,每次检查当前p和q节点的值是否相等,如果相等再判断左右子树是否对称。

代码解读
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:
bool isSymmetric(TreeNode* root) {
// 1.检查是否轴对称
// 既然要检测树,那么如何去找左右节点呢?-> 使用指针移动
return root == nullptr || recur(root -> left, root -> right);
}
/**
终止条件 L 和 R 同时越过叶节点,此树从顶至底的节点都对称,
*/
private:
bool recur(TreeNode* L, TreeNode* R) {
if (L == nullptr && R ==nullptr) return true;
if(L == nullptr || R == nullptr || L -> val != R ->val) return false;
return recur(L -> left, R -> right) && recur(L->right, R->left);
}
};
二叉树的直径
给你一颗二叉树的根节点,返回该树的直径
二叉树的直径是指树中任意两个节点之间最长路径的长度。这条路径可能经过也可能不经过根节点root,两节点之间路径的长度由它们之间的边数表示。

解题思路
首先需要知道求直径相当于求什么。一条路径的长度为该路径经过的节点数减一,所以求直径等效于求路径经过节点数的最大值减一。比如4到1就是三个节点,减去一个节点就是2.
而任意一个路径都可以被看作是某一个节点为起点,从其左儿子和右儿子向下便利的路径拼接得到。
假设我们知道对于该节点的左儿子向下便利经过最多的节点数L和其右儿子向下便利经过节点R,那么以该节点为起点的路径经过节点数最大值为 L+R+1.
cpp
class Solution {
int ans; // 全局变量: 记录二叉树中 最长路径的节点总数
// 定义一个递归函数: 计算以rt为根的子树的最大深度
int depth(TreeNode* rt) {
// 递归终止条件: 空节点深度为 0
if(rt == NULL) {
return 0;
}
// 后序便利: 先计算左子树的深度L
int L = depth(rt -> left);
// 再计算右子树深度 R
int R = depth(rt -> right);
// 核心: 当前节点的路径长度 = 左深度 + 右深度 +1
ans = max(ans, L + R + 1); // 这里是更新当前的全局最大值
return max(L,R) +1;
}
public:
// 主函数:求二叉树的直径
int diameterOfBinaryTree(TreeNode* root) {
// 初始化:最少一个节点
ans = 1;
// 递归便利整颗树, 计算所以节点的路径
depth(root);
// 直接 = 最长路径节点数 - 1
return ans - 1;
}
}
102.二叉树的层序遍历
给你二叉树的根节点root,返回其节点值的层序遍历。
**输入:root = [3,9,20,null,null,15,7]
输出:[[[3],[9,20],[15,7]]

思路分析
首先题目要求是按层打印,又被称为二叉树的广度优先搜索BFS. 而BFS是借助队列的先入先出的特性来实现的。
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) {
// 队列,用于BFS, 存储节点指针, 利用先进先出实现层序
queue<TreeNode*> que;
// 用于存放最终结果;每一层一组节点值
vector<vector<int>> res;
// 如果根节点非空,先将根节点入队
if(root != nullptr) que.push(root);
// 队列不为空,说明还有节点未遍历
while(!que.empty()) {
// 临时数组,存放当前这一层的所有节点值
vector<int> tmp;
// 关键: 只循环当前层的节点个数
for(int i = que.size();i > 0; --i) {
// 取出队首节点
root = que.front(); // 取出首队列和弹出首队列
// 谈出队首节点
que.pop();
// 将节点值加入当前层数组
tmp.push_back(root-> val);
// 左孩子不为空则入队,作为下一层节点
if( root -> left != nullptr) que.push(root -> left);
if (root -> right != nullptr) que.push(root -> right);
}
// 当前层便利完毕,这一层结果加入最终结果
res.push_back(tmp);
}
return res;
}
};