题解 | #按之字形顺序打印二叉树#

按之字形顺序打印二叉树

http://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0

解法一:使用队列

据题意,需要按照每一层的方式打印二叉树,因此较为直接的解法为「层次遍历」。

二叉树的层次遍历通过队列实现较为方便,步骤如下:

  1. 初始情况,根结点入队列;
  2. 定义变量size记录当前队列长度;
  3. 对于「当前队列」,遍历其所有元素:依次出队列、访问该元素、左右孩子入队列。注意:新入队列的「左右孩子」应当在下一层被访问,因此循环次数为size次。
  4. 重复上述步骤直至队列为空。

步骤如图所示。

图片说明

此外,此题目要求「之字形」打印,因此定义变量level记录当前层的打印方向。

代码如下:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        vector<vector<int> > res; 
        if (!pRoot)
            return res; 
        queue<TreeNode*> q; // 定义队列
        q.push(pRoot); // 根结点入队列
        int level = 0;
        while (!q.empty()) {
            vector<int> arr; // 定义数组存储每一行结果
            int size = q.size(); // 当前队列长度
            for (int i = 0; i < size; i++) {
                TreeNode* tmp = q.front(); // 队头元素
                q.pop(); 
                if (!tmp) // 空元素跳过
                    continue;
                q.push(tmp->left); // 左孩子入队列
                q.push(tmp->right); // 右孩子入队列
                if (level % 2 == 0) {
                    // 从左至右打印
                    arr.push_back(tmp->val);
                } else { // 从右至左打印
                    arr.insert(arr.begin(), tmp->val);
                }
            }
            level++; // 下一层,改变打印方向
            if (!arr.empty())
                res.push_back(arr); // 放入最终结果
        }
        return res;
    }

};

该方法遍历到树的所有结点,时间复杂度为O(N);该方法定义了队列q,空间复杂度为O(N)。

解法二:使用栈

由本题所要求的「之字形打印」,可以联想到栈的「先入后出」的特性。由于栈仅能在一端进行入栈出栈操作,因此需要定义两个栈,交替使用。

步骤如下(如图所示):

  1. 定义两个栈stk1,stk2;将根结点入栈stk1;
  2. 对于下一层,应是「从右至左」打印,因此需要遍历栈stk1、访问每一个元素,并将每一元素的孩子按照「先右孩子、后左孩子」的顺序入栈stk2;将访问的结点保存;
  3. 对于下一层,应是「从左至右」打印,因此需要遍历栈stk2、访问每一个元素,并将每一元素的孩子按照「先左孩子、后右孩子」的顺序入栈stk1;将访问的结点保存;
  4. 重复上述操作,直至两个栈全为空。

图片说明

根据上述思路,实现的代码如下:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        vector<vector<int> > res; 
        if (!pRoot) 
            return res; 
        stack<TreeNode*> stk1, stk2; // 定义两个栈
        stk1.push(pRoot); // 根结点入栈
        while (!stk1.empty() || !stk2.empty()) { // 两个栈全空时循环结束
            vector <int> arr; 
            while (!stk1.empty()) {
                TreeNode* p = stk1.top(); 
                stk1.pop(); 
                arr.push_back(p->val); // 访问栈顶
                if (p->left) stk2.push(p->left); // 左孩子入栈
                if (p->right) stk2.push(p->right); // 右孩子入栈
            }
            if (arr.size())
                res.push_back(arr); // 保存结果
            arr.clear(); // 清空
            while (!stk2.empty()) {
                TreeNode* p = stk2.top(); 
                stk2.pop(); 
                arr.push_back(p->val); // 访问栈顶
                if (p->right) stk1.push(p->right); // 右孩子入栈
                if (p->left) stk1.push(p->left); // 左孩子入栈
            }
            if (arr.size())
                res.push_back(arr); // 保存结果
        }
        return res;
    }

};

该方法遍历到树的所有结点,时间复杂度为O(N);该方法定义了双栈,空间复杂度为O(N)。

全部评论
2和3步写错了啊,2是先左后右,3是先右后左
点赞 回复 分享
发布于 2023-09-08 11:06 广东

相关推荐

原来已经一年了,因为没有加任何实验室没有学长学姐带,再一次偶然的机会下刷到我们学校的牛肉哥,和他聊天之后发现他也没加实验室能进大厂,我就燃起了希望,去年大概&nbsp;4&nbsp;月份找好路线&nbsp;零基础&nbsp;开始学&nbsp;5&nbsp;月背八股和开始刷算法很难受&nbsp;7-8&nbsp;月焦虑躯体化害怕找不到实习&nbsp;9&nbsp;月找到一家像样的小厂去实习了&nbsp;4&nbsp;个月大三上期末考试结束之后&nbsp;1&nbsp;月份回来边实习边准备工作压力很大&nbsp;当时只有字节、百度、商汤的面试,字节三面挂了,百度&nbsp;oc,商汤&nbsp;二面挂(差评&nbsp;无效面试),之后来深圳百度实习之后还是觉得不甘心一直没把算法和八股扔下一直在准备,百度实习的时候&nbsp;mt&nbsp;交给我一个特别重要的工作数据库迁移(特别感谢&nbsp;mt&nbsp;,这个需求学到了很多东西处理了一堆线上问题),本来看着暑期他们面试都很困难,然后听说百度要涨实习薪资(然而&nbsp;5&nbsp;月并没有涨),就想着留在百度吧也懒得面试了,4&nbsp;月&nbsp;20&nbsp;多的时候字节&nbsp;hr&nbsp;打电话约面问我要不要尝试一下询问了&nbsp;1&nbsp;月份三面为啥会挂有没有学习&nbsp;ai&nbsp;知识(因为字节这边后端岗位偏&nbsp;ai),我来到百度之后全面拥抱&nbsp;AI&nbsp;也认识了我的好兄弟&nbsp;X&nbsp;哥,他在百度&nbsp;XX&nbsp;部门&nbsp;Agent&nbsp;实习,他属于是我&nbsp;Agent&nbsp;的启蒙老师,来百度之后一直在了解&nbsp;AI&nbsp;这一块,我就接受了字节的面试,一面的时候&nbsp;20&nbsp;分钟实习拷打然后突然说&nbsp;30&nbsp;分钟代码考核我心就凉了以为是&nbsp;kpi,算法题是手撕高并发安全下的令牌桶限流器,我写了整整&nbsp;80&nbsp;多行代码最后也写出来了,但是从来没看到过出这种题能&nbsp;oc&nbsp;的我也就不管了,后边面试也是很顺利但是流程有点长可能一直在横向吧总结结果是好的!!!感谢这一年努力的自己和遇到的各位互联网大佬分享的知识!!!ps&nbsp;图二纯感慨&nbsp;(觉得🍬请不要喷我)欢迎大家一起交流学习呀!!!!
点赞 评论 收藏
分享
评论
30
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务