LeetCode/树的层次遍历

1. 二叉树的层平均值

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        auto averages = vector<double>();
        auto q = queue<TreeNode*>();
        q.push(root);
        while (!q.empty()) {
            double sum = 0;//每一层的和
            int size = q.size();//当前层的节点数量
            for (int i = 0; i < size; i++) {
                auto node = q.front();
                q.pop();
                sum += node->val;//求和
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            averages.push_back(sum / size);
        }
        return averages;
    }
};

2. 每个树行中找最大值

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        queue<TreeNode*> q;
        q.push(root);
        int cur = 1;//每次出栈的次数,表示遍历一层
        int next=0;//记录下一层用作下一次遍历
        int max_;
        while(cur>0){
            max_ = INT_MIN;
            while(cur>0){//这里可以改为for循环更加简洁
                TreeNode* point = q.front();
                max_ = max(max_,point->val);
                q.pop();
                cur--;
                if(point->left){
                    q.push(point->left);
                    next++;
                }
                if(point->right){
                    q.push(point->right);
                    next++;
                }
            }
            res.push_back(max_);
            cur = next;
            next = 0;
        }
        return res;
    }
};

3. 二叉树的锯齿形层序遍历

//使用双端队列,这里用于存储值
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        if (!root) return ans;

        queue<TreeNode*> nodeQueue;//队列
        nodeQueue.push(root);
        bool isOrderLeft = true;

        while (!nodeQueue.empty()) {
            deque<int> levelList;//双向队列存储值
            int size = nodeQueue.size();
            for (int i = 0; i < size; ++i) {
                auto node = nodeQueue.front();//从头部出
                nodeQueue.pop();
                if (isOrderLeft) {
                    levelList.push_back(node->val);//队列的操作,按入队顺序输出
                } else {
                    levelList.push_front(node->val);//相当于栈的操作,反向输入
                }
                if (node->left) {
                    nodeQueue.push(node->left);
                }
                if (node->right) {
                    nodeQueue.push(node->right);
                }
            }
            ans.emplace_back(vector<int>{levelList.begin(), levelList.end()});
            isOrderLeft = !isOrderLeft;//改变方向
        }

        return ans;
    }
};

4. 二叉树的右视图

//层次遍历
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> right;
        if(!root) return right;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int size = q.size();//当前层的节点数量
            for (int i = 0; i < size; i++) {
                auto node = q.front();
                q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
                if(i==size-1) right.push_back(node->val);
            }
        }
        return right;
    }
};
深度优先(先序)
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> right;
        dfs(root,0,right);
        return right;
    }
    void dfs(TreeNode* root,int layer,vector<int> &right){
        if(!root) return;
        if(layer==right.size()) right.push_back(root->val);
        dfs(root->right,layer+1,right);
        dfs(root->left,layer+1,right);
    }
};

5. 二叉树最大宽度

//层次遍历,编号标记节点
class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        unsigned long long res = 0;
        deque<pair<TreeNode *, unsigned long long>> arr;
        arr.push_back({root, 1L});
        while (!arr.empty()) {
            int n = arr.size();
            res = max(res, arr.back().second - arr.front().second + 1);
            for (int i=0;i<n;i++) {
                TreeNode * node = arr.front().first;
                unsigned long long index = arr.front().second;
                arr.pop_front();
                if (node->left) 
                    arr.push_back({node->left, index * 2});
                if (node->right) 
                    arr.push_back({node->right, index * 2 + 1});
            }
        }
        return res;
    }
};
深度优先(后序) ``` class Solution { public: unordered_map levelMin;//记录当前层最左编号 int widthOfBinaryTree(TreeNode* root) { return dfs(root, 1, 1);//初始一层且编号为1 } unsigned long long dfs(TreeNode* node, int depth, unsigned long long index) { if (node == nullptr) return 0LL;//边界条件 if (!levelMin.count(depth)) levelMin[depth] = index; //记录第一趟最左编号 unsigned long long left = dfs(node->left, depth + 1, index * 2);//左递归 unsigned long long right = dfs(node->right, depth + 1, index * 2 + 1);//右递归 unsigned long long cur = index - levelMin[depth] + 1;//当前编号与最左编号距离 return max({cur, left, right}); }; }; ```
posted @ 2022-07-25 21:27  失控D大白兔  阅读(26)  评论(0编辑  收藏  举报