层序遍历的十道题
102.二叉树的层序遍历
题目链接https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
/**
* 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) {
queue<TreeNode*> que;
vector <vector<int>> result;
if(root!=NULL){
que.push(root);}
while(!que.empty()){
vector<int> res;//每一次循环都要重新开一个数组,最后合到一个二维数组里面
int size=que.size();
while(size--){
TreeNode* node=que.front();
que.pop();
res.push_back(node->val);//res保存的是当前层的结点
if(node->left){que.push(node->left);}//往队列里加左节点
if(node->right){que.push(node->right);}//往队列里加右节点
}
result.push_back(res);//把每一层的数据放到二维数组里面
}
return result;
}
};
107.二叉树的层序遍历||
题目链接https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/
思路感觉跟上一题差不多,就是把最后的数组反向一下。
while(size--){
TreeNode* Node=que.front();
que.pop();
res.push_back(Node->val);
if(Node->left)res.push_back(Node->left->val);//错误解法
if(Node->right)res.push_back(Node->right->val);//错误解法
}
最开始这样第一组数据没过(hhh居然只有一组), 思路是每一层往外pop的数一维数组里,然后赶紧把要pop数的左节点和右节点放在队列里进行下次操作。也就是数组里放的是这一层的值。这里犯的错就是把结点的左右结点的值都放数组里面了。这样的话,我根节点pop之后我把左右结点放在数组里之后队列里面没值了就会跳出循环,那左右结点的如果还有子节点就不会继续遍历,当然就不能通过了。
我滴妈,这个调用用.还是->简直就是运气试出来的(离谱),这里队列里面存的是指针地址,但是队列是当对象来调用的。这里的Node放的是队列里的第一个元素,就是指针了,指针进行访问指向对象成员用->。队列这里相当于对象,对象访问成员用. 所以是que.pop(),by the way,所以栈,队列往里面加元素都是push,而vector和deque都是push_back。栈访问栈顶元素是用top访问,队列访问头部元素用front。
下面是正确代码
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*> que;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int size=que.size();
vector<int> res;
while(size--){
TreeNode* Node=que.front();//Node取的是que队列第一个节点所以是指针
que.pop();
res.push_back(Node->val);
if(Node->left)que.push(Node->left);//Node是指针要用->
if(Node->right)que.push(Node->right);//que是对象要用.
}
result.push_back(res);
}
reverse(result.begin(),result.end());//把数组反向就是自底向上层序遍历
return result;
}
};
199.二叉树的右视图
题目链接https://leetcode.cn/problems/binary-tree-right-side-view/description/
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> res;//只要右节点的话一维数组就够了
queue<TreeNode*> que;
if(root!=NULL){//要判断不为空才能推进队列,不加这里直接报错了
que.push(root);}
while(!que.empty()){
int size=que.size();
while(size--){
TreeNode* Node=que.front();
que.pop();
res.push_back(Node->val);
if(Node->right)que.push(Node->right);
}
}
return res;
}
};
637.二叉树的层平均值
题目链接 https://leetcode.cn/problems/average-of-levels-in-binary-tree/
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode*> que;
vector<double> res;//注意返回的vector是double类型的
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
double sum=0;
int size=que.size();
int tmp=size;
while(size--){
TreeNode* Node=que.front();
que.pop();
sum+=Node->val;
if(Node->left)que.push(Node->left);
if(Node->right)que.push(Node->right);
}
res.push_back(sum/tmp);//这里不能直接/size,size这里是遍历结束后的值。
//不是每层的节点数,可以先保存一个tmp来除就没有问题
}
return res;
}
};
429.二叉树的层序遍历
题目链接https://leetcode.cn/problems/n-ary-tree-level-order-traversal/description/
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
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;
vector<vector<int>> result;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int size=que.size();
vector<int> res;
while(size--){
Node* node=que.front();
for(int i=0;i<node->children.size();i++){
que.push(node->children[i]);//往里面推每一个孩子节点
}
que.pop();
res.push_back(node->val);
}
result.push_back(res);
}
return result;
}
};
最开始在for循环语句里面写的是这个,当然一直报错
for(int i=0;i<node->children.size();i++){
que.push(node->children->val);}
因为在这里children是一个代表多个点的向量(vector<Node*> children),而不是单个节点。因此,不能通过 node->children
直接访问其值,因为它是一个集合。而且这里的que里面要存储的是指针如果node->children->val那就是往里推的是值了。
515.在每个树行中找最大值
题目链接https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/
/**
* 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<int> largestValues(TreeNode* root) {
queue<TreeNode*> que;
vector<int> res;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int max=INT_MIN;//要在每一次循环之外赋值
int size=que.size();
while(size--){
TreeNode* node=que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
max=node->val>max?node->val:max;//比较每一层数据的大小
}
res.push_back(max);
}
return res;
}
};
最开始我把max赋值size--的外面就一直报错
while(!que.empty()){//错误解法
int max;
int size=que.size();
while(size--){
max=INT_MIN;//在每一次循环之内赋值
TreeNode* node=que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
max=node->val>max?node->val:max;//如果在里面赋值就只会和INT_MIN比,会把最后
} //一个值设置为最大值
res.push_back(max);
}
116.填充每个节点的下一个右侧节点指针
题目链接https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/description/
117.填充每个节点的下一个右侧节点指针||
题目链接https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/description/
笑死,这两道题简直一模一样,差别只有116是完全二叉树,117不是
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
Node* front;
Node* node;
int size=que.size();
for(int i=0;i<size;i++){
if(i==0){
front=que.front();
node=que.front();//在每一层的开头把node也设置为第一个节点,因为往里面推左节点和右节点用的是node
que.pop(); //node没有指向后面node->left会报错
}
else{
node=que.front();
que.pop();
front->next=node;//把上一个节点指向下一个节点
front=node;
}
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
}
node->next=NULL;//最后一个节点指向空
}
return root;
}
};
104.二叉树的最大深度
题目链接https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/
/**
* 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 maxDepth(TreeNode* root) {
queue<TreeNode*> que;
int depth=0;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int size=que.size();
while(size--){
TreeNode* node=que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
}
depth++;
}
return depth;
}
};
111.二叉树的最小深度
题目链接https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/
/**
* 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 minDepth(TreeNode* root) {
queue<TreeNode*> que;
int depth=0;
if(root==NULL) {return 0;}
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int size=que.size();
depth++;//每一层加一
while(size--){
TreeNode* node=que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
if(!(node->left)&&!(node->right)){return depth;}//遇到有空的结点就返回
}
}
return depth;
}
};
最开始depth的值一直不对,因为这里把只要是左节点右节点是空的就计数,那就会把根节点一并记上,正确的思路应该是遍历每一层之前把depth++,如果遇到空节点就直接返回。
while(!que.empty()){//错误解法
int size=que.size();
while(size--){
TreeNode* node=que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
if(!(node->left)&&!(node->right)){depth++;}
}
}
return depth;
}