【代码随想录算法训练Day15】二叉树的层序遍历、LeetCode 226.翻转二叉树、LeetCode 101.对称二叉树

Day15 二叉树第二天

二叉树的层序遍历

学会层序遍历,直接做10道题。
没错,整整十道题

LeetCode 102.二叉树的层序遍历

这道题与我们以前遇到的层序遍历不同的地方在于,它要求将每一层的节点都放在一个数组里,最后输出的是一个按层分行的二维数组,所以我们在遍历每一行时要记录这一行的节点个数,将不同行的节点分开。

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        vector<vector<int>> res;
        if(root) q.push(root);
        while(!q.empty()){
            int size=q.size();
            vector<int> vec;
            while(size--){
                TreeNode* node=q.front();q.pop();
                vec.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            res.push_back(vec);
        }
        return res;
    }
};

LeetCode 107.二叉树的层序遍历II

与上一题一样,把最终结果数组翻转一下即可。

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode*> q;
        vector<vector<int>> res;
        if(root) q.push(root);
        while(!q.empty()){
            int size=q.size();
            vector<int> vec;
            while(size--){
                TreeNode* node=q.front();q.pop();
                vec.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            res.push_back(vec);
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

LeetCode 199.二叉树的右视图

此题仍是层序遍历,每次遍历到每一层最后一个元素时将它记录进数组即可。

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> q;
        vector<int> res;
        if(root) q.push(root);
        while(!q.empty()){
            int size=q.size();
            while(size--){
                TreeNode* node=q.front();q.pop();
                if(size==0) res.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
        }
        return res;
    }
};

LeetCode 637. 二叉树的层平均值

层序遍历时计算每一层的元素之和,再把平均值加入数组。

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> q;
        vector<double> res;
        if(root) q.push(root);
        while(!q.empty()){
            int size=q.size();
            double sum=0;
            for(int i=0;i<size;i++){
                TreeNode* node=q.front();q.pop();
                sum+=node->val;
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            res.push_back(sum/size);
        }
        return res;
    }
};

LeetCode 429. N 叉树的层序遍历

从二叉变为N叉,但其内核还是不变的。

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> que;
        if (root!=NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            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;
    }
};

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

层序遍历时每一行找最大值。

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

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

层序遍历的单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。

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

LeetCode 117. 填充每个节点的下一个右侧节点指针 II

上一题的解法本身对于非完全二叉树也适用,所以本题可以直接用上一题的代码。

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

LeetCode 104. 二叉树的最大深度

层序遍历一层结束时深度+1。

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root==NULL) return 0;
        int depth=0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size=que.size();
            depth++; // 记录深度
            for (int i=0; i<size;i++) {
                TreeNode* node=que.front();
                que.pop();
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return depth;
    }
};

LeetCode 111. 二叉树的最小深度

最小深度的意思是只要找到一个左右孩子均为空的节点,那就找到最小深度了。

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root==NULL) return 0;
        int depth=0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size=que.size();
            depth++; // 记录最小深度
            for (int i = 0; i < size; i++) {
                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;
    }
};

二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时又发现队列的一个应用了)。
连续打十个,我真棒!

LeetCode 226.翻转二叉树

递归,按照前序遍历的方式前进,在每个节点翻转他的两个子节点即可。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(!root) return root;
        swap(root->left,root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

LeetCode 101. 对称二叉树

对称二叉树的关键是要保证子节点也是对称的,所以要用后序递归遍历树,递归先处理对称的子节点,再将是否对称的结果交给父节点。

class Solution {
public:
    bool compare(TreeNode* left,TreeNode* right){
        if(!left && !right) return true;
        else if(left && !right) return false;
        else if(!left && right) return false;
        else if(left->val!=right->val) return false;

        bool outside=compare(left->left,right->right);
        bool inside=compare(left->right,right->left);
        bool res=outside&&inside;
        return res;
    }

    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        return compare(root->left,root->right);
    }
};

又是充实的一天。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值