今天学习的是二叉树层序遍历。
基本的二叉树层序遍历方法:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*>que;
if(root!=NULL)que.push(root);
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;
}
};
题例: 102. 二叉树的层序遍历
同一个思路可以解决很多和这个类似的问题
例如:由下自上的层序遍历;实际上不用考虑从底层向上,只要把result数组反转即可。
二叉树的右视图,加上判断节点是否是右节点即可。每层遍历size次,则size-1处为每层最后一个元素。层计数的size在层序遍历中有很大作用。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*>que;
if(root!=NULL)que.push(root);
vector<int>vec;
while(!que.empty()){
int size = que.size(); //控制每层的元素送入一个数组
for(int i =0; i < size; i++){
TreeNode* node = que.front();
que.pop();
if(i == size-1){
vec.push_back(node->val);
}
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);//将下一层的节点按顺序放入队列
}
}
return vec;
}
};
加上求每层的和即可,注意题目的数据类型要求的是双浮点值类型。
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> result;
queue<TreeNode*>que;
if(root!=NULL)que.push(root);
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(node->left)que.push(node->left);
if(node->right)que.push(node->right);//将下一层的节点按顺序放入队列
}
result.push_back(sum/size);
}
return result;
}
};
429. N 叉树的层序遍历 需要用一个循环来替代直接加入左右叶节点
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> result;
queue<Node*>que;
if(root!=NULL)que.push(root);
while(!que.empty()){
vector<int>vec;
int size = que.size(); //控制每层的元素送入一个数组
for(int i =0; i < size; i++){
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for(int i =0; i<node->children.size();i++){
if(node->children[i]) que.push(node->children[i]);
};//将下一层的节点按顺序放入队列
}
result.push_back(vec);
}
return result;
}
};
515. 在每个树行中找最大值 使用一个INT_MIN的值来标定每层的最大值
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> result;
queue<TreeNode*>que;
if(root!=NULL)que.push(root);
while(!que.empty()){
int max = INT_MIN;
int size = que.size(); //控制每层的元素送入一个数组
for(int i =0; i < size; i++){
TreeNode* node = que.front();
que.pop();
max = node->val > max? node->val:max;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(max);
}
return result;
}
};
向右设置一个指针,本质还是在层中拉指针
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
while (!que.empty()) {
int size = que.size();
Node* nodePre;
Node* node;
for (int i = 0; i < size; i++) {
if (i == 0) {
nodePre = que.front(); // 取出一层的头结点
que.pop();
node = nodePre;
} else {
node = que.front();
que.pop();
nodePre->next = node; // 本层前一个节点next指向本节点
nodePre = nodePre->next;
}
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
nodePre->next = NULL; // 本层最后一个节点指向NULL
}
return root;
}
};
2. 翻转二叉树
递归和迭代都可以解决这个问题,迭代在确定节点后交换左右节点。这里使用前序遍历,首先确定根节点再将子节点反转。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*>st;
if(root!=NULL)st.push(root);
while(!st.empty()){
int size = st.size();
for(int i = 0; i <size; i++){
TreeNode* node=st.top();
st.pop();
swap(node->left,node->right);
if(node->left) st.push(node->left);
if(node->right) st.push(node->right);
}
}
return root;
}
};
3. 判断二叉树是否对称
要考虑到所有不满足对称的情况,以及需要比较的对象
class Solution {
public:
bool compare(TreeNode* left,TreeNode* right){
if(left==NULL&&right!=NULL)return false;
else if(left!=NULL&&right==NULL)return false;
else if(left==NULL&&right==NULL)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 both = outside&&inside;
return both;
}
bool isSymmetric(TreeNode* root) {
if(root==NULL)return true;
return compare(root->left,root->right);
}
};