题目:102.二又树的层序遍历
文章链接:代码随想录
题目链接:力扣题目链接
详解:队列先进先出,符合层序遍历的广度优先遍历;栈先进后出使用于模拟深度优先遍历的递归遍历逻辑
解法1:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
// 创建一个存放二叉树指针的队列
queue<TreeNode*> que;
// 把第一个根节点放入队列
if(root != NULL) que.push(root);
// 返回的二维数组
vector<vector<int>> result;
// 终止条件,队列为空
while(!que.empty()) {
// 快照,记录每层的元素数量
int size = que.size();
// 用于存放每层的元素数组
vector<int> vec;
for(int i=0; i<size; i++){
// 把根节点的元素放入数组中
TreeNode* node = que.front();
que.pop(); //弹出
vec.push_back(node->val);
// 把该节点的孩子放入队列中
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
//把每层的数组放入二维数组中
result.push_back(vec);
}
return result;
}
};
递归法:利用depth记录当前递归所在的层数,多少层数的递归,就放在第几行的vector中
// 递归方法
void order(TreeNode* cur, vector<vector<int>>& result, int depth) {
// 终止条件
if (cur==NULL) return;
// 如果结果集的大小等于深度,则创建一个vector容器,相当于给result多开了一层
if (result.size() == depth) result.push_back(vector<int>());
result[depth].push_back(cur->val); // 把当层元素放入
// 因为下一层终止条件有判断指针是否为空,所以不用在上层进行判断
order(cur->left, result, depth+1);
order(cur->right, result, depth+1);
}
// 层级遍历-模版
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
int depth = 0;
order(root, result, depth);
return result;
}
题目:107.二叉树的层序遍历II
文章链接:代码随想录
题目链接:力扣题目链接
解法1:
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
// 创建一个存放二叉树指针的队列
queue<TreeNode*> que;
// 把第一个根节点放入队列
if(root != NULL) que.push(root);
// 返回的二维数组
vector<vector<int>> result;
// 终止条件,队列为空
while(!que.empty()) {
// 快照,记录每层的元素数量
int size = que.size();
// 用于存放每层的元素数组
vector<int> vec;
for(int i=0; i<size; i++){
// 把根节点的元素放入数组中
TreeNode* node = que.front();
que.pop(); //弹出
vec.push_back(node->val);
// 把该节点的孩子放入队列中
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
//把每层的数组放入二维数组中
result.push_back(vec);
}
// 将最后的二维数组进行反转
reverse(result.begin(), result.end()); // 只是反转了第一层,并不会打乱第二层里面的数组元素
return result;
}
};
题目:199.二叉树的右视图
题目链接:力扣题目链接
解法1:
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
// 创建队列
queue<TreeNode*> que;
// 把根节点放入
if(root !=NULL) que.push(root);
// 创建结果数组
vector<int> result;
// 终止条件,队列为空
while(!que.empty()){
// 快照
int size = que.size();
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
// 每一层的最后一个则加入结果数组中
if(i == size-1) result.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
题目:637.二叉树的层平均值
题目链接:力扣题目链接
解法1:
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
// 队列
queue<TreeNode*> que;
if(root != NULL) que.push(root);
vector<double> result;
while(!que.empty()){
int size = que.size();
double sum = 0; // 记录单层总和
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
sum += node->val;
// 遍历到单层最后一个元素,开始操作
if(i == size-1){
double average = sum / size;
result.push_back(average);
}
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
题目:429.N又树的层序遍历
题目链接:力扣题目链接
解法1:
class Node{
public:
int val;
vector<Node*> children; // 存放节点的数组
// 构造函数
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
// 队列
queue<Node*> que;
if(root != NULL) que.push(root);
vector<vector<int>> result;
while(!que.empty()){
int size = que.size();
vector<int> vec;
for(int i=0; i<size; i++){
Node* node = que.front();
que.pop();
vec.push_back(node->val);
// 拥有多个节点的孩子
for(int j=0; j<node->children.size(); j++){
que.push(node->children[j]);
}
}
result.push_back(vec);
}
return result;
}
};
题目:515.在每个树行中找最大值
题目链接:力扣题目链接
解法1:
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
// 队列
queue<TreeNode*> que;
if(root != NULL) que.push(root);
vector<int> result;
while(!que.empty()){
int size = que.size();
int max = INT32_MIN; // 先定义一个int类型最小值
for(int i=0; i<size; i++){
TreeNode* node = que.front();
que.pop();
// if(max < node->val) max = node->val;
// 三目运算符
max = max > node->val ? max :node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(max);
}
return result;
}
};
题目:116.填充每个节点的下一个右侧节点指针
题目链接:力扣题目链接
解法1:
class Solution {
public:
Node* connect(Node* root) {
// 队列
queue<Node*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
for(int i=0; i<size; i++){
Node* node = que.front(); // [2,3]
que.pop(); // [2]
if(i == size-1) node->next =NULL;
else{
node->next = que.front(); // 指向队列中的头元素
}
if(node->left) que.push(node->left); // [3,4]
if(node->right) que.push(node->right); // [3,4,5]
}
}
return root;
}
};
题目:117.填充每个节点的下一个右侧节点指针Il
题目链接:力扣题目链接
解法1:
// 队列
queue<Node*> que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
for(int i=0; i<size; i++){
Node* node = que.front(); // [2,3]
que.pop(); // [2]
if(i == size-1) node->next =NULL;
else{
node->next = que.front(); // 指向队列中的头元素
}
if(node->left) que.push(node->left); // [3,4]
if(node->right) que.push(node->right); // [3,4,5]
}
}
return root;
题目:104.二又树的最大深度
题目链接:力扣题目链接
解法1:
class Solution {
public:
int maxDepth(TreeNode* root) {
// 队列
queue<TreeNode*> que;
int result = 0; // 记录深度
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
result ++;
for(int i=0; i<size; i++){
TreeNode* node = que.front(); // [2,3]
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
题目:111.二又树的最小深度
题目链接:力扣题目链接
解法1:
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == NULL) return 0;
// 队列
queue<TreeNode*> que;
int result = 0; // 记录深度
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
result ++;
for(int i=0; i<size; i++){
TreeNode* node = que.front(); // [9,20]
que.pop();
// 当左右节点都为空时,返回深度
if(!node->left && !node->right) return result;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
题目:226.翻转二叉树
题目链接:力扣题目链接
解法1:递归法
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
// 确定终止条件
if(root == NULL) return root;
// 前序
swap(root->left, root->right); //中
invertTree(root->left); // 左
invertTree(root->right); // 右
return root;
}
};
解法2:层序遍历法
TreeNode* inverTree(TreeNode* root) {
if (root == NULL) return NULL;
queue<TreeNode*>que;
que.push(root);
while (!que.empty()) {
int size = que.size();
while (size--) {
TreeNode* cur = que.front();
swap(cur->left, cur->right);
que.pop();
if (cur->left)que.push(cur->left);
if (cur->right)que.push(cur->right);
}
}
return root;
}
题目:101.对称二叉树
题目链接:力扣题目链接
解法1:收集孩子的信息,向上进行反馈,用后序
class Solution {
public:
//1.确定传入的值(左右节点),返回bool类型,比较结果
bool compare(TreeNode* left, TreeNode* right){
//2.确定终止条件 左右都为空,对称, 返回true
if(left == NULL && right != NULL) return false;
// 单边为空的情况,则不对称
else if(left != NULL && right == NULL) return false;
else if(left == NULL && right == NULL) return true; // 两遍都为空时不向下遍历,返回true
// 两边都不为空,则比较值
else if(left->val != right->val) return false; // 没有用else剩下只有两值相等的情况
// 3.处理单层 后序遍历
bool outnode = compare(left->left, right->right); // 比较外侧节点
bool innode = compare(left->right, right->left); // 比较内侧节点
bool result = outnode && innode;
return result;
}
bool isSymmetric(TreeNode* root) {
return compare(root->left, root->right);
}
};
解法2:迭代法
bool isSymmetric(TreeNode* root) {
//return iscompare(root->left, root->right);
// 迭代法
if (root == NULL)return true; //空节点也为对称
queue<TreeNode*>que;
que.push(root->left);
que.push(root->right);
while (!que.empty()) {
TreeNode* leftnode = que.front(); que.pop();
TreeNode* rightnode = que.front(); que.pop();
// 右为空,左为空,则为对称,继续
if (rightnode == NULL && leftnode == NULL) continue;
// 经过上面的判断后,就只剩单边为空的情况了
if (rightnode == NULL || leftnode == NULL)return false;
// 比较值相同
else if (leftnode->val != rightnode->val)return false;
// 放入节点
que.push(leftnode->left);
que.push(rightnode->right);
que.push(leftnode->right);
que.push(rightnode->left);
}
return true; //当节点都访问完,没有false则为true
}