代码随想录算法训练营第十五天 | LeeCode 226. 翻转二叉树,101. 对称二叉树,广度优先遍历十本番

题目链接:226. 翻转二叉树 - 力扣(LeetCode)

class Solution
{
public:
    TreeNode *invertTree(TreeNode *root)
    {
        queue<TreeNode *> que;
        if (root)
            que.push(root);

        while (!que.empty())
        {
            int size = que.size();

            for (int i = 0; i < size; i++)
            {
                TreeNode *node = que.front();
                que.pop();

                TreeNode *tmp;
                tmp = node->right;
                node->right = node->left;
                node->left=tmp;

                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }

        return root;
    }
};

思路
第一个想法就是一层层遍历,一层层交换次序

解题方法
使用队列辅助的层序遍历,每到一层就交换一次左右结点,一直遍历下去。
我们先把根节点入队列,然后进入循环进行操作。
循环的次数为n次,n是当前层的结点数。-->出队列的同时把该节点的左右子节点入队列。这个操作一直执行到循环结束。
这样子做有什么作用呢,细想一下,队列有先进先出的特性,我们操作n次,保证把这一层所有结点都出了队列,同时又把下一层所有节点入了队列(因为我们出队列的同时把其左右叶子加入了队列)。
如此,我们就完成了广度优先遍历。
然后,我们只需要在每次添加结点入队列的时候,调换一下左右节点就行。

复杂度
时间复杂度:

O(n)

空间复杂度:

O(n)

题目链接:101. 对称二叉树 - 力扣(LeetCode)

class Solution
{
public:
    bool compare(TreeNode *left, TreeNode *right)
    {
        // 首先排除空结点的情况
        if (left == nullptr && right != nullptr)
            return false;
        else if (left != nullptr && right == nullptr)
            return false;
        else if (left == nullptr && right == nullptr)
            return true;
        // 排除了空结点,再排除值不相等
        else if (left->val != right->val)
            return false;

        
        //此时的情况是左右节点都不为空并且值都相等
        //此时才做递归,做下一层的判断
        bool outside=compare(left->left,right->right);
        bool inside=compare(left->right,right->left);
        return outside&&inside;
    }
    bool isSymmetric(TreeNode *root)
    {
        if (root == nullptr)
            return true;
        return compare(root->left, root->right);
    }
};

思路
比较左右外层和内层是否相等即可

解题方法
可以使用队列或者栈进行辅助的迭代法,将内外层分别装进去再进行操作。这里使用递归法来解决。原理是利用递归一层层的走下去,保证每次判断两边都是外层或内层。

复杂度
时间复杂度:

O(n)

空间复杂度:

O(n)

以下是广度优先十道题

题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode)

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

题目链接:107. 二叉树的层序遍历 II - 力扣(LeetCode)

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

题目链接:199. 二叉树的右视图 - 力扣(LeetCode)

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<int> result;
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (i == (size - 1)) result.push_back(node->val); // 将每一层的最后元素放入result数组中
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};

思路
本质上还是用层序遍历来遍历每一层

解题方法
做这道题前先要搞清楚右视图是什么。简而言之就是从右边看过去,每一层都只能看到一个结点。这时候要思考的就来了,如果右子树有东西,那我们自然看到的就是右子树上的结点。那么如果右子树没东西呢?我们当然看到的就是左子树上面的结点,所以在解题的时候不能只考虑右子树上的结点,也要看左子树。
那这么说这道题岂不是很麻烦?
非也,仔细想想,其实我们并不用分左右讨论,我们要在意的,只有每一层最后一个结点就行,这个结点,就是我们从右视图看到的结点。

复杂度
时间复杂度:

O(n)

空间复杂度:

O(n)

题目链接:637. 二叉树的层平均值 - 力扣(LeetCode)

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

题目链接:429. N 叉树的层序遍历 - 力扣(LeetCode)

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> que;
        vector<vector<int>> result;
        if(root) que.push(root);

        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(Node *tmp:node->children){
                    if(tmp) que.push(tmp);
                }
            }

            result.push_back(vec);
        }

        return result;
    }
};

思路
本质上和二叉树层序遍历一样

解题方法
利用队列先进先出的特性,先把根节点入队列。然后进行操作n次,n为本层的结点数------->出队列的同时把本结点全部子节点入队。
这样子保证了把本层所有结点都出了队列,同时把下一层所有结点入队列。
这就是层序遍历的基本思想。

复杂度
时间复杂度:

O(n)

空间复杂度:

O(n)

题目链接:515. 在每个树行中找最大值 - 力扣(LeetCode)

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=que.front()->val;
            for (int i = 0; i < size; i++)
            {
                TreeNode *node = que.front();
                que.pop();
                if(node->val>max) max=node->val;
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            result.push_back(max);
        }
        return result;
    }
};

题目链接:116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)


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

题目链接:117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)

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

题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)

class Solution {
public:
    int maxDepth(TreeNode* root) {
        queue<TreeNode *> que;
        if(root) que.push(root);
        int depth=0;
        
        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;
    }
};

题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)

class Solution {
public:
    int minDepth(TreeNode* root) {
        queue<TreeNode *> que;
        if(root) que.push(root);
        int depth=0;
        
        while(!que.empty()){
            int size=que.size();
            depth++;

            for(int i=0;i<size;i++){
                TreeNode *node=que.front();
                que.pop();
                
                if(!node->left&&!node->right) return depth;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }

        return depth;
    }
};

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值