返回

C++ 如何高效解决剑指 Offer 32 - 从上到下打印二叉树 II?

闲谈

问题

给定一棵二叉树,设计一个算法,从上到下按层打印这棵二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:

          1
         / \
        2   3
       / \  / \
      4   5 6   7

从上到下按层打印这棵二叉树,得到:

[
  [1],
  [2,3],
  [4,5,6,7]
]

C++ 解决方案

以下是用 C++ 语言实现的解决方案:

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

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;
        if (root == nullptr) {
            return result;
        }

        queue<TreeNode*> q;
        q.push(root);

        while (!q.empty()) {
            int size = q.size();
            vector<int> level;
            for (int i = 0; i < size; i++) {
                TreeNode* node = q.front();
                q.pop();
                level.push_back(node->val);
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            result.push_back(level);
        }

        return result;
    }
};

算法分析

这种算法采用广度优先搜索 (BFS) 的思想来解决问题。BFS 是一种按层次遍历树或图的数据结构的算法,它从根节点开始,一层一层地遍历树或图中的所有节点。

  1. 初始化一个队列 q,并把根节点压入队列。
  2. 只要队列不为空,就执行以下步骤:
    • 从队列中取出最前面的节点 node
    • node 的值压入结果向量 result 的当前层向量。
    • 如果 node 有左孩子,就把左孩子压入队列。
    • 如果 node 有右孩子,就把右孩子压入队列。
  3. 重复步骤 2,直到队列为空。

复杂度分析

  • 时间复杂度:O(N),其中 N 是二叉树的节点数。BFS 算法需要访问二叉树中的每个节点一次,因此时间复杂度为 O(N)。
  • 空间复杂度:O(N),BFS 算法需要使用队列来存储二叉树的节点,在最坏的情况下,队列中可能存储所有的节点,因此空间复杂度为 O(N)。

总结

这种算法提供了一种简洁有效的方法来从上到下按层打印二叉树。它易于理解和实现,并且具有良好的时间和空间复杂度。