【代码随想录|二叉树的层序遍历】

层序遍历的十道题

 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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值