代码随想录算法训练营:13/60

非科班学习算法day13 | LeetCode144:二叉树的前序遍历 ,Leetcode145: 二叉树的后序遍历,Leetcode97:二叉树的中序遍历 ,LeetCode589:N叉树的前序遍历,Leetcode102:二叉树的层序遍历 ,Leetcode199: 二叉树的右视图 ,Leetcode637: 二叉树的层平均值,Leetcode429: N叉树的层序遍历,Leetcode515: 在每个树行中找最大值,Leetcode116: 填充每个节点的下一个右侧节点指针

目录

介绍

一、基础概念补充:

1.递归的三个步骤

二、LeetCode题目

1.LeetCode144:二叉树的前序遍历 

题目解析

 2.Leetcode145:二叉树的后序遍历 

题目解析

3.Leetcode97: 二叉树的中序遍历

题目解析

 

4.Leetcode589: N叉树的前序遍历

题目解析

5.Leetcode102:二叉树的层序遍历 

题目解析

6.Leetcode199: 二叉树的右视图 

7.Leetcode637: 二叉树的层平均值

8.Leetcode429: N叉树的层序遍历

9.Leetcode515: 在每个树行中找最大值

10.Leetcode116: 填充每个节点的下一个右侧节点指针

总结


介绍

包含LC的几道题目,还有相应概念的补充。

相关图解和更多版本:

代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF

一、基础概念补充:

1.递归的三个步骤

确定返回值和传入参数;

确定中止条件;

写一次递归的逻辑。

不要过分关注后面的过程,容易绕进去。

    

二、LeetCode题目

1.LeetCode144:二叉树的前序遍历 

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

题目解析

       分别采用递归和迭代方法给出,其中递归分为引用函数的递归和直接递归。

 第一种递归c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 设置递归函数
    vector<int> Traverasl(TreeNode* cur, vector<int>& vec) {
        // 设置中止出口
        if (cur == nullptr)
            return vec;

        // 递归体
        vec.push_back(cur->val);
        Traverasl(cur->left, vec);
        Traverasl(cur->right, vec);

        // 返回结果
        return vec;
    }
    vector<int> preorderTraversal(TreeNode* root) {
        // 创建vec
        vector<int> result;

        // 调用函数
        return Traverasl(root, result);
    }
};

 第二种递归c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> result;
    vector<int> preorderTraversal(TreeNode* root) 
    { 
        //设置中止出口
        if(root == nullptr) return result;

        //迭代体
        result.push_back(root->val);        //中
        preorderTraversal(root->left);      //左边遍历
        preorderTraversal(root->right);     //右边遍历
        
        //设置最终返回值
        return result;
    }
};

  迭代c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 创建模拟栈
    stack<TreeNode*> st;
    // 创建结果vector
    vector<int> result;
    // 迭代函数
    vector<int> preorderTraversal(TreeNode* root) {
        // 插入根节点
        if (root != nullptr)
            st.push(root);

        // 设置迭代条件
        while (!st.empty()) {
            // 记录栈顶
            TreeNode* cur_node = st.top();

            // 弹栈
            st.pop();

            // 中间节点进入结果vector
            result.push_back(cur_node->val);

            // 进栈该节点的左右子节点
            if (cur_node->right != nullptr)
                st.push(cur_node->right);
            if (cur_node->left != nullptr)
                st.push(cur_node->left);

            // 弹栈操作开始迭代
        }

        return result;
    }
};

 2.Leetcode145:二叉树的后序遍历 

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

题目解析

       分别采用递归和迭代方法给出,其中递归分为引用函数的递归和直接递归。

 第一种递归C++代码如下: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 创建递归函数
    vector<int> Traversal(TreeNode* cur, vector<int>& vec) {
        // 设置中止条件
        if (cur == nullptr)
            return vec;

        // 递归体
        Traversal(cur->left, vec);
        Traversal(cur->right, vec);
        vec.push_back(cur->val);

        // 返回
        return vec;
    }
    vector<int> postorderTraversal(TreeNode* root) {
        // 创建结果函数
        vector<int> result;

        // 调用函数
        return Traversal(root, result);
    }
};

  第二种递归c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //创建vec
    vector<int> result;
    vector<int> postorderTraversal(TreeNode* root) 
    {
        //设置中止出口
        if(root == nullptr) return result;

        //递归体
        postorderTraversal(root->left);
        postorderTraversal(root->right);
        result.push_back(root->val);

        //返回
        return result;
    }
};

迭代c++代码如下: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 创建模拟栈
    stack<TreeNode*> st;

    // 创建结果vector
    vector<int> result;

    vector<int> postorderTraversal(TreeNode* root) {
        // 初始化
        if (root != nullptr)
            st.push(root);

        // 迭代
        while (!st.empty()) {
            // 记录栈顶
            TreeNode* cur_node = st.top();

            // 弹栈
            st.pop();

            // 元素进入结果
            result.push_back(cur_node->val);

            // 加入左右子节点
            if (cur_node->left != nullptr)
                st.push(cur_node->left);
            if (cur_node->right != nullptr)
                st.push(cur_node->right);
        }
        reverse(result.begin(), result.end());
        return result;
    }
};

3.Leetcode97: 二叉树的中序遍历

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

题目解析

        分别采用递归和迭代方法给出,其中递归分为引用函数的递归和直接递归。

第一种递归C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 创建递归函数
    vector<int> Traversal(TreeNode* cur, vector<int>& vec) {
        // 设置递归出口
        if (cur == nullptr)
            return vec;

        // 递归体
        Traversal(cur->left, vec);
        vec.push_back(cur->val);
        Traversal(cur->right, vec);

        //
        return vec;
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;

        return Traversal(root, result);
    }
};

 第二种递归C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //创建返回值
    vector<int> result;
    vector<int> inorderTraversal(TreeNode* root) 
    {
        if(root == nullptr) return result;
        inorderTraversal(root->left);
        result.push_back(root->val);
        inorderTraversal(root->right);

        return result;
    }
};

注意点1:

 

4.Leetcode589: N叉树的前序遍历

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

题目解析

       分别采用递归和迭代方法给出,其中递归分为引用函数的递归和直接递归。

递归C++代码如下:

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    // 创建结果vector
    vector<int> result;

    vector<int> preorder(Node* root) {
        // 创建中止出口
        if (root == nullptr)
            return result;

        // 递归体
        result.push_back(root->val);
        for (auto child : root->children) {
            preorder(child);
        }

        return result;
    }
};

迭代c++代码如下:

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    stack<Node*> st;
    vector<int> result;

    vector<int> preorder(Node* root) {
        if (root == nullptr)
            return result;
        st.push(root);
        while (!st.empty()) {
            Node* cur_node = st.top();
            st.pop();
            result.push_back(cur_node->val);
            for (auto it = cur_node->children.rbegin();
                 it != cur_node->children.rend(); it++) {
                st.push(*it);
                //vector<Node*>::reverse_iterator
            }
        }
        return result;
    }
};

5.Leetcode102:二叉树的层序遍历 

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

题目解析

       下面的题目用的都是层序遍历,非常相似,只是在处理的时候可能有不同的统计变量或者操作,这里直接给出代码。

C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        //建立数组接受结果
        vector<vector<int>> result;

        //建立控制队列
        queue<TreeNode*>que;

        //检验根节点是否为空
        if(root != nullptr)
        {
            que.push(root);
        }

        //弹出控制队列的所有元素为止
        while(!que.empty())
        {
            //创建当前层数组接受结果
            vector<int> current_vec;

            //记录当前层数元素数量
            int size = que.size();

            //设置循环弹出当前层数量的元素
            for(;size > 0; size--)
            {
                //记录元素即将弹出元素
                TreeNode* current_node = que.front();

                //将该元素记录到current_vec
                current_vec.push_back(current_node->val);

                //弹出
                que.pop();

                //添加左右节点
                if(current_node->left)
                {
                    que.push(current_node->left);
                }
                if(current_node->right)
                {
                    que.push(current_node->right);
                }
            }

            //当前层弹出结束,更新队列长度
            size = que.size();

            //将当前队列添加到结果
            result.push_back(current_vec);
        }
        return result;
    }
};

6.Leetcode199: 二叉树的右视图 

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

C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) 
    {
        //创建结果数列
        vector<int> result;

        //创建队列
        queue<TreeNode*> que;

        //插入根节点
        if(root != nullptr) que.push(root);

        //初始化层元素数量
        int size = que.size();

        //循环弹出节点
        while(!que.empty())
        {
            for(int i = 0; i < size; i++)
            {
                //记录头部
                TreeNode* cur_node = que.front();
                //弹出
                que.pop();

                //当到达最后一个,单次判断
                if(i == size - 1)
                {
                    result.push_back(cur_node->val);
                }

                //添加左右节点
                if(cur_node->left != nullptr) que.push(cur_node->left);
                if(cur_node->right != nullptr) que.push(cur_node->right);
            }

            //更新
            size = que.size();
        }
        return result;
    }
};

7.Leetcode637: 二叉树的层平均值

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

C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) 
    {
        //创建结果数组
        vector<double> result;

        //创建队列
        queue<TreeNode*> que;

        //插入根节点
        if(root != nullptr) que.push(root);

        //初始化层元素数量
        int size = que.size();

        //循环弹栈
        while(!que.empty())
        {
            //初始化和
            double sum = 0.0;

            for(int i = 0; i < size; i++)
            {
                //记录当前节点信息
                TreeNode* cur_node = que.front();
                
                //更新和
                sum += (double)cur_node->val;

                //弹栈
                que.pop();

                //加入子节点
                if(cur_node->left != nullptr) que.push(cur_node->left);
                if(cur_node->right != nullptr) que.push(cur_node->right);
            }

            //计算平均值
            double cur_avg = sum / size;

            //更新size
            size = que.size();
            
            //下一循环已经
            result.push_back(cur_avg);
        }
        return result;
    }
};

8.Leetcode429: N叉树的层序遍历

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

C++代码如下:

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) 
    {
        //建立数组接受结果
        vector<vector<int>> result;

        //建立队列
        queue<Node*> que;

        //插入根节点
        if(root != NULL)
        {
            que.push(root);
        }

        //初始化size
        int size = que.size();

        //循环
        while(!que.empty())
        {
            //建立当前层接收数组
            vector<int> cur_vec;

            while(size--)
            {
                //保存栈顶
                Node* cur_node = que.front();

                //插入结果
                cur_vec.push_back(cur_node->val);

                //弹栈
                que.pop();

                //遍历插入子节点

                for(auto it:cur_node->children)
                {
                    if(it)
                    {
                        que.push(it);
                    }
                }

            }
            //更新
            size = que.size();

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

9.Leetcode515: 在每个树行中找最大值

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

C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> largestValues(TreeNode* root) 
    {
        //建立接受数组
        vector<int> result;

        //建立辅助队列
        queue<TreeNode*> que;

        //插入根节点
        if(root != nullptr)
        {
            que.push(root);
        }

        //初始化数组长度
        int size = que.size();

        //循环
        while(!que.empty())
        {
            vector<int> cur_vec;
            while(size--)
            {
                //保留头部信息
                TreeNode* cur_node = que.front();

                //弹栈
                que.pop();

                //插入
                cur_vec.push_back(cur_node->val);
                
                //左右子节点
                if(cur_node->left != nullptr) que.push(cur_node->left);
                if(cur_node->right != nullptr) que.push(cur_node->right);
 
            }
            //更新size
            size = que.size();

            //max
            auto it = max_element(cur_vec.begin(), cur_vec.end());
            int vec_max = *it;
            //max to re
            result.push_back(vec_max);
        }
        return result;
    }
};

 

10.Leetcode116: 填充每个节点的下一个右侧节点指针

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

C++代码如下:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        // 创建辅助队列
        queue<Node*> que;

        // 插入根节点
        if (root != NULL) {
            que.push(root);
        }

        // 初始化数组长度
        int size = que.size();

        // 设置循环
        while (!que.empty()) {
            while (size--) {
                // 记录当前头节点
                Node* cur_node = que.front();

                // 弹栈
                que.pop();

                // 记录当前头节点
                Node* cur_node2 = que.front();

                // 设置指向
                if (size == 0) {
                    cur_node->next = NULL;
                } else {
                    cur_node->next = cur_node2;
                }

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

            // 更新size
            size = que.size();
        }
        return root;
    }
};

总结


打卡第13天,第一次看二叉树的时候哭了,坚持!!!

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值