【剑指Offer-32-III】从上到下打印二叉树 III

问题

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

示例

解答1:迭代

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        deque<TreeNode*> d;
        int cnt = 0;
        if (root) d.push_back(root);
        while (!d.empty()) {
            cnt++;
            vector<int> ans;
            int n = d.size();
            if (cnt & 1) { // 奇数层,从左往右
                for (int i = 0; i < n; i++) {
                    TreeNode* cur = d.front(); d.pop_front();
                    ans.push_back(cur->val);
                    if (cur->left) d.push_back(cur->left);
                    if (cur->right) d.push_back(cur->right);

                }
            } else { // 偶数层,从右往左
                for (int i = 0; i < n; i++) {
                    TreeNode* cur = d.back(); d.pop_back();
                    ans.push_back(cur->val);
                    if (cur->right) d.push_front(cur->right);
                    if (cur->left) d.push_front(cur->left);
                }
            }
            res.push_back(ans);
        }
        return res;
    }
};

重点思路

一个比较简单的做法是先正常打印,然后把偶数层的输出reverse一下。当然,这会降低算法的效率。本算法使用双端队列deque,在奇数层,正常打印,双端队列deque做队列queue的操作;在偶数层,需要从右往左打印,此时我们需要从队尾开始取数,类似于栈,那么下一批节点入队时就只能加在队头。此时,先入右节点,再入左节点,才能保证后续顺序正确。

解答2:递归

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        recur(root, 0);
        for (int i = 0; i < res.size(); i++) // 分奇偶层反转
            if (i & 1) reverse(res[i].begin(), res[i].end());
        return res;
    }
private:
    vector<vector<int>> res;
    void recur(TreeNode* root, int level) {
        if (!root) return;
        if (res.size() <= level) res.push_back({}); // 拓展二维数组
        res[level].push_back(root->val);
        recur(root->left, level + 1); // 递归下一层
        recur(root->right, level + 1);
    }
};

重点思路

比较方便的思路还是正常层序遍历,然后对最后的结果做后处理。

posted @ 2021-02-24 21:00  tmpUser  阅读(43)  评论(0编辑  收藏  举报