一. 这题是重点学习题
作者:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1. 如何遍历一棵树, 有两种通用的遍历树的策略:
深度优先搜索(DFS)
在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历,中序遍历和后序遍历。
宽度优先搜索(BFS)
我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。 下图中的顶点按照访问的顺序编号,按照 1-2-3-4-5 的顺序来比较不同的策略。
本问题就是用宽度优先搜索遍历来划分层次:[[1], [2, 3], [4, 5]].
方法 1:递归
1. 先放上自己的思路.
//自己写的,接下来可以对比一下官方的.
class Solution {
public:
vector<vector<int>> levels;
void helper(TreeNode* root, int level) {
if (root == NULL) return;
//如果levels中没有代表当前等级的vector,
//就创建.
if (levels.size() == level) {
vector<int> tmp;
levels.push_back(tmp);
}
//有的话直接加入对应等级的vector.
levels[level].push_back(root->val);
//递归左右子树.
helper(root->left, level + 1);
helper(root->right, level + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
if (root == NULL) return levels;
//自顶向下的分治策略.
//helper的含义是给定当前节点root,
//等级level,看如何放入levels中.
helper(root, 0);
return levels;
}
};
2. 参考官方(好吧和自己写的没什么区别).
复杂度分析
时间复杂度:O(N),因为每个节点恰好会被运算一次。 空间复杂度:O(N),保存输出结果的数组包含 N
个节点的值。
方法 2:迭代
1. 上面的递归方法也可以写成迭代的形式。我们将树上顶点按照层次依次放入队列结构中,队列中元素满足 FIFO(先进先出)的原则。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> levels;
if (root == NULL) return levels;
//定义队列, 广度优先搜索.
queue<TreeNode*> tree;
tree.push(root);
int level = 0;
while (!tree.empty()) {
vector<int> tmp;
levels.push_back(tmp);
//范围number的节点都是同一个层级的.
int number = tree.size();
for (int i = 0; i < number; i++) {
TreeNode* node = tree.front(); tree.pop();
levels[level].push_back(node->val);
if (node->left != NULL) tree.push(node->left);
if (node->right != NULL) tree.push(node->right);
}
level++;
}
return levels;
}
};