目录
层序遍历,都可以在同一套代码上进行修改。
层序遍历*10
102. 二叉树的层序遍历
-
层序迭代
/**
* 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>> result;
queue<TreeNode*> que;
if (root != nullptr) que.push(root);
while (!que.empty()) {
vector<int> vec;
int size = que.size();
for (int i = 0; i < size; i++) { // 遍历每一层的节点
TreeNode* p = que.front();
que.pop();
vec.push_back(p->val);
if (p->left) que.push(p->left);
if (p->right) que.push(p->right);
}
result.push_back(vec);
}
return result;
}
};
-
前序递归
/**
* 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) {}
* };
*/
// 递归法
// 输入参数:当前节点指针TreeNode* cur , 存储结果的二维数组 vector<vector<int>>& vec ,二叉树层序 depth
// 返回值: void 返回值
// 单层逻辑:遇到指针为空则返回;判断当前层次,如果当前层遍历完,则扩展下一层;根节点不断扩展左右子节点;
// 终止条件:指针为空;
class Solution {
private:
void order(TreeNode* cur, vector<vector<int>>& vec, int depth) { // 此处 depth 为数值传递,函数内的修改不影响函数外的值
if (cur == nullptr) return;
if (vec.size() == depth) vec.push_back(vector<int>()); // 写入空一维数组,扩展一层
vec[depth].push_back(cur->val);
order(cur->left, vec, depth + 1);
order(cur->right, vec, depth + 1);
}
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
int depth = 0;
order(root, result, depth);
return result;
}
};c
107. 二叉树的层序遍历 II
给你二叉树的根节点
root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
reverse(result.begin(), result.end()); // 在自上向下的基础上,增加一行反转
199. 二叉树的右视图
给定一个二叉树的 根节点
root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
if (i == size-1) result.push_back(p->val);
637. 二叉树的层平均值
给定一个非空二叉树的根节点root
, 以数组的形式返回每一层节点的平均值。与实际答案相差10-5
以内的答案可以被接受。
{
sum += p->val;
}
result.push_back(sum/size);
429. N 叉树的层序遍历
for (int i = 0; i < p->children.size(); i++) {
if (p->children[i] != nullptr)
que.push(p->children[i]);
}
515. 在每个树行中找最大值
给定一棵二叉树的根节点root
,请找出该二叉树中每一层的最大值。
int max_num = INT_MIN; // INT_MIN int 类型的最小值 -2147483648
{
if (p->val > max_num) max_num = p->val; // 记录每一层的最大值
}
116. 填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。
if (i == size-1) p->next = nullptr;
else p->next = que.front();
117. 填充每个节点的下一个右侧节点指针 II
给定一个 任意二叉树 (和上一题相比代码不变)
if (i == size-1) p->next = nullptr;
else p->next = que.front();
104. 二叉树的最大深度
给定一个二叉树
root
,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
result++; // 每进行一层遍历,就++
111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
逐层搜索,当遇到叶子节点(不是根节点)时,就是最小深度。
result++;
{
if (p != root && p->left == nullptr && p->right == nullptr) return result;
}
226.翻转二叉树
题目链接:226. 翻转二叉树
给你一棵二叉树的根节点
root
,翻转这棵二叉树,并返回其根节点。示例 1:
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2:
输入:root = [2,1,3] 输出:[2,3,1]示例 3:
输入:root = [] 输出:[]
前序递归:
-
思考过程:
翻转二叉树,实际只要把每一个节点的 left 和 right 翻转一下
但关键的是,采用哪一种遍历方式?
- 深度优先(前中后序 递归法、迭代法)、广度优先(层序遍历 迭代法)
优先掌握递归法:
- 输入及返回:TreeNode* invertTree(TreeNode* root);
- 单层逻辑:交换left 和 right 节点;
- 终止条件:节点指针为空;
-
力扣代码:
/**
* 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:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) return root; // 中
swap(root->left, root->right);
invertTree(root->left); // 左
invertTree(root->right); // 右
return root;
}
};
101.对称二叉树
题目链接:101. 对称二叉树
给你一个二叉树的根节点
root
, 检查它是否轴对称。示例 1:
输入:root = [1,2,2,3,4,4,3] 输出:true示例 2:
输入:root = [1,2,2,null,3,null,3] 输出:false
后序递归:
-
思考过程:
- 比较两个子树的里侧和外侧的元素是否相等;
- 需要思考使用哪种遍历方式? 前中后序 递归遍历——>采用后序遍历
递归三步思考:
- 输入及返回值:TreeNode* left, TreeNode* right 左子树节点 右子树节点
- 终止条件:对两个节点的指针进行是否为空节点、数值是否相等的判断,否则直接返回 false;
- 单层递归逻辑:处理左右节点都不为空,且数值相同的情况:判断两个子树的内侧节点和外侧节点是否相等。
-
解题细节
- 先对两个节点的指针进行是否为空节点、数值是否相等的判断,否则直接返回 false;
- 确保左右节点都不为空,且数值相同,再进入递归。
-
力扣代码:
/**
* 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 compare(TreeNode* left, TreeNode* right) { // 指向左右两个子树的指针
// 首先排除空节点的情况
if (left == nullptr && right != nullptr) return false;
else if (left != nullptr && right == nullptr) return false;
else if (left == nullptr && right == nullptr) return true;
// 排除了空节点,再排除数值不相同的情况
else if (left->val != right->val) return false;
// 剩下的情况就是:左右节点都不为空,且数值相同的情况
// 进行递归,做下一层判断
bool outside = compare(left->left, right->right); // 左子树:左 右子树:右
bool inside = compare(left->right, right->left); // 左子树:右 右子树:左
bool isSame = outside && inside; // 左子树:中 右子树:中
return isSame;
}
bool isSymmetric(TreeNode* root) {
if (root == nullptr) return true;
return compare(root->left, root->right);
}
};