代码随想录训练营day15

第六章 二叉树part02

1.LeetCode. 翻转二叉树

1.1题目链接:226.翻转二叉树

文章讲解:代码随想录
视频讲解:B站卡哥视频

1.2思路:该题目采用递归遍历的话可以使用前序遍历(中左右),也可以采用后序遍历(左右中),但是采用中序遍历的话容易造成出错,这里也可以采用中序遍历但不是表面上的中序遍历需要进行根据实际情况更改的中序遍历(即左中左,根据实例可以分析出来);采用层序遍历也可以实现;

1.3附加代码如下所示:

//递归法 中序遍历
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==NULL)return root;
        swap(root->left,root->right);//中
        invertTree(root->left);//左
        invertTree(root->right);//右
        return root;


    }
};

2.LeetCode.对称二叉树

2.1题目链接:101. 对称二叉树

文章讲解:代码随想录
视频讲解:B站卡哥视频

2.2思路:本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中.

2.3附加代码如下所示:

//正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
class Solution {
public:
    bool compare(TreeNode*left,TreeNode*right)
    {
        //首先排除空节点
        if(left==NULL&&right!=NULL)return false;
        else if(left!=NULL&&right==NULL)return false;
        else if(left==NULL&&right==NULL)return true;
        // 排除了空节点,再排除数值不相同的情况
        else if(left->val!=right->val)return false;
        // 此时就是:左右节点都不为空,且数值相同的情况
        // 此时才做递归,做下一层的判断
        else
        {
            bool outside=compare(left->left,right->right);
            bool inside=compare(left->right,right->left);
            bool isSame=outside&&inside;
            return isSame;
        }
        
    }
    bool isSymmetric(TreeNode* root) {
        if(root==NULL)return true;
        return compare(root->left,root->right);
         

    }
};

3.LeetCode.二叉树层序遍历

3.1题目链接:102.二叉树的层序遍历 107.二叉树的层次遍历II 199.二叉树的右视图 637.二叉树的层平均值 429.N叉树的层序遍历 515.在每个树行中找最大值 116.填充每个节点的下一个右侧节点指针 117.填充每个节点的下一个右侧节点指针II 104.二叉树的最大深度 111.二叉树的最小深度

文章讲解:代码随想录
视频讲解:B站卡哥视频

3.2思路:二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时又发现队列的一个应用了)。

3.3附加代码如下所示:

(102.二叉树的层序遍历)

//二叉树的层序遍历递归法
class Solution {
public:

    void orderlayer(TreeNode*cur,vector<vector<int>>&result,int depth)
    {
        if(cur==nullptr)return;
        if(result.size()==depth)result.push_back(vector<int>());
        result[depth].push_back(cur->val);
        orderlayer(cur->left,result,depth+1);
        orderlayer(cur->right,result,depth+1);
    }

    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>result;
        int depth=0;
        orderlayer(root,result,depth);
        return result; 
       
    }
};
//层序遍历法
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>result;
        queue<TreeNode*>que;
        if(root==NULL)return result;
        else que.push(root);
        while(!que.empty())
        {
            int size=que.size();//记录每一层的元素个数
            vector<int>vec;//用来保存每一层的元素
            while(size--)
            {
                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)

//相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>>result;
        queue<TreeNode*>que;
        if(root==nullptr)return result;
        else que.push(root);
        while(!que.empty())
        {

            int size=que.size();//记录每一层的元素数目
            vector<int>vec;
            while(size--)
            {
                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.二叉树的右视图)

//层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int>result;//因为题目要求只保存有侧视图的元素所以不需要二维数组一维数组就行
        queue<TreeNode*>que;
        if(root==nullptr) return result;
        else que.push(root);
        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);
                if(node->left)que.push(node->left);
                if(node->right)que.push(node->right);
            }
            
            
        }
        return result;

    }
};

(637.二叉树的层平均值)

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double>average;
        queue<TreeNode*>que;
        if(root==nullptr)return average;
        else que.push(root);
        while(!que.empty())
        {
            int size=que.size();
            
            double sum=0;//这里要采用double类型,不然结果会出错,用来统计每一层的和
            for(int i=0;i<size;i++)
            {
                
                TreeNode*node=que.front();
                que.pop();
                sum+=node->val;
                if(node->left)que.push(node->left);
                if(node->right)que.push(node->right);
            }
            average.push_back(sum/size);//将每一层的平均值放入数组中
        }
        return average;
    }
};

(429.N叉树的层序遍历)

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())
        {
            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 j=0;j<node->children.size();j++)
                {
                    if(node->children[j]) que.push(node->children[j]);
                }
            }
            result.push_back(vec);
        }
        return result;
        
    }
};

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

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int>result;
        queue<TreeNode*>que;
        if(root!=NULL) que.push(root);
        while(!que.empty())
        {
            int size=que.size();
            int max=INT_MIN;//用来存放每行也就是二叉树每层的最大值,但是max的最小值不是零,这是有符号的数值,应该是INT_MIN ,通常是 -2147483648
            for(int i=0;i<size;i++)
            {
                TreeNode*node=que.front();
                que.pop();
                max=max>node->val ?max:node->val;//取每一行的最大值
                if(node->left)que.push(node->left);
                if(node->right)que.push(node->right);

            }
            result.push_back(max);
        }
        return result;
    }
};

(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*node;
            Node*nodepre;
            for(int i=0;i<size;i++)
            {
                if(i==0)//取出一层的第一个头节点
                {
                    node=que.front();
                    que.pop();
                    nodepre=node;
                }
                else
                {
                    node=que.front();
                    que.pop();
                    nodepre->next=node;//本层前一个结点指向本节点
                    nodepre=nodepre->next;

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

            }
            nodepre->next=NULL;//本层最后一个节点指向NULL
        }
        return root;
    }
    
};

(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*node;
            Node*nodepre;
            for(int i=0;i<size;i++)
            {
                if(i==0)//取出一层的第一个头节点
                {
                    node=que.front();
                    que.pop();
                    nodepre=node;
                }
                else
                {
                    node=que.front();
                    que.pop();
                    nodepre->next=node;//本层前一个结点指向本节点
                    nodepre=nodepre->next;

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

            }
            nodepre->next=NULL;//本层最后一个节点指向NULL
        }
        return root;
    }
    
};

(104.二叉树的最大深度)

//本题求二叉树的深度从另一方面来说就是求层序遍历的深度,所以采用层序遍历就能直接得到结果
class Solution {
public:
    int maxDepth(TreeNode* root) {
        queue<TreeNode*>que;
        if(root!=NULL)que.push(root);
        int count=0;
        while(!que.empty())
        {
            int size=que.size();
            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);
            }
            count++;
        }
        return count;

    }
};

(111.二叉树的最小深度)

//需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点
class Solution {
public:
    int minDepth(TreeNode* root) {
        queue<TreeNode*>que;
        if(root!=NULL)que.push(root);
        int count=0;
        while(!que.empty())
        {
            int size=que.size();
            count++;//因为根节点已经加入了表明深度为1了;这是计算多少个节点数目了
            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==NULL&&node->right==NULL)//也就是首先碰到的左右子树均为空指针的就是最近子树
                {
                    return count;
                }
            }
        }
        return count;

    }
};
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值