【层序遍历专场练习Ⅱ】429. N叉树的层序遍历、515. 在每个树行中寻找最大值、116. 填充每个节点的下一个右侧节点指针、104二叉树的最大深度&559N叉树、11. 二叉树的最小深度

429. N叉树的层序遍历

题目描述:给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

解答:思路与二叉树的层序遍历一致,主要在于子节点入队时稍有不同。N叉树判断子节点的是否为空(大小是否为0),非空时依次进行入队即可。其他操作与二叉树层序遍历一样。

代码实现:

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>layer;
            int size = que.size();
            for (int i = 0; i<size; i++){
                Node* p = que.front();
                layer.push_back(p->val);
                que.pop();
                if (p->children.size() != 0){//子节点入队
                    vector<Node*>ch = p->children;
                    int size_Ch = ch.size();
                    for (int j = 0; j<size_Ch; j++)
                        que.push(ch[j]);
                }
            }
            result.push_back(layer);
        }
        return result;
    }
};

515. 在每个树行中寻找最大值

题目描述:给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

解答:依旧采用层序遍历,稍加修改,保存每一层的最大值即可。

代码实现:

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*>que;
        vector<int>result;
        if (root)
            que.push(root);
        while(!que.empty()){
            int size = que.size();
            int max = INT_MIN;
            for (int i = 0; i<size; i++){
                TreeNode* p = que.front();
                que.pop();
                if (max < p->val) max = p->val;
                if (p->left) que.push(p->left);
                if (p->right) que.push(p->right);
            }
            result.push_back(max);
        }
        return result;
    }
};

116. 填充每个节点的下一个右侧节点指针

题目描述:

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL

解答:涉及到同一层的节点,考虑使用层序遍历。遇到非最右侧节点,令其next指向队列头的元素(即为同一层的下一个元素),遇到最右侧节点指向NULL即可

代码实现:

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*> que;
        if (root)
            que.push(root);
        while(!que.empty()){
            int size = que.size();
            for (int i = 0; i<size; i++){
                Node* p = que.front();
                que.pop();
                if (i == size-1)
                    p->next = NULL;
                else{
                    p->next = que.front();
                }
                if (p->left) que.push(p->left);
                if (p->right) que.push(p->right);
            }
        }
        return root;
    }
};

104. 二叉树的最大深度

题目描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

        说明: 叶子节点是指没有子节点的节点。

解答:

法一:采用层序遍历,每遍历一层后计数加1.

代码实现:

class Solution {
public:
    int maxDepth(TreeNode* root) {
        queue<TreeNode*>que;
        if (root)   que.push(root);
        int num = 0;
        while(!que.empty()){
            num++;
            int size = que.size();
            for (int i = 0; i<size; i++){
                TreeNode* p = que.front();
                que.pop();
                if (p->left) que.push(p->left);
                if (p->right) que.push(p->right);
            }
        }
        return num;
    }
};

 法二:采用递归法

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == NULL) return 0;
        int num = max(maxDepth(root->left), maxDepth(root->right)) + 1;
        return num;
    }
};

559. N 叉树的最大深度

题目描述:

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

解答:

法一:递归法

N叉树的最大深度和二叉树的最大深度类似,只是需要访问的子树数量变多了而已。

代码实现:

class Solution {
public:
    int maxDepth(Node* root) {
        if (root == 0) return 0;
        int depth = 0;
        for (int i = 0; i < root->children.size(); i++) {
            depth = max (depth, maxDepth(root->children[i]));
        }
        return depth+1;
    }
};

法二:迭代解法

层序遍历最为合适,采用层序遍历。

代码实现:

class Solution {
public:
    int maxDepth(Node* root) {
        if (root == 0) return 0;
        queue<Node*>que;
        que.push(root);
        int depth = 0;
        while(!que.empty()){
            int size  = que.size();
            depth++;
            for (int i =0; i<size; i++){
                Node* p = que.front();
                que.pop();
                vector<Node*>children;
                children = p->children;
                for(int j = 0; j<children.size(); j++)
                    que.push(children[j]);
            }
            
        }
        return depth;
    }
};

111. 二叉树的最小深度

题目描述:给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

        说明:叶子节点是指没有子节点的节点。

解答:

法一:

采用层序遍历,计算层的深度,当遇到左右子节点均为空时,即找到最小深度,返回结果

代码实现:

class Solution {
public:
    int minDepth(TreeNode* root) {
        queue<TreeNode*>que;
        if (root)   que.push(root);
        int num = 0;
        while(!que.empty()){
            num++;
            int size = que.size();
            for (int i = 0; i<size; i++){
                TreeNode* p = que.front();
                que.pop();
                if (p->left) que.push(p->left);
                if (p->right) que.push(p->right);
                if (! p->left && ! p->right) return num;
            }
        }
        return num;
    }

};

法二:

采用递归法,左右中的遍历处理方式。需要注意的是在遇到节点左孩子为空右孩子不为空,或者左孩子不为空右孩子为空的情况要特殊处理,此时并不是最小高度。左空右非空时返回其右子树的最小高度,左非空右空返回其左子树的最小高度。

代码实现:

class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root == NULL) return 0;
        int left = minDepth(root->left);
        int right = minDepth(root->right);
        // 当一个左子树为空,右不为空,这时并不是最低点
        if (root->left == NULL && root->right != NULL) { 
            return 1 + right;
        }   
        // 当一个右子树为空,左不为空,这时并不是最低点
        if (root->left != NULL && root->right == NULL) { 
            return 1 + left;
        }
        int num = min(left,right) + 1;
        return num;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值