题目概述:
解法:
一、利用广度优先遍历
非常显然,如果把树看成一种简化的图,前序遍历就是一种广度优先遍历,那么自然可以按照广度优先遍历的思想实现前序遍历,具体来说,我们需要一个队列q,先检查root是否为空,不为空则让root入队,并且为返回的二维数组容器vec扩容,根据我们后面的设计,会发现q的大小正是二叉树的这一层结点的个数,所以用
c
u
r
r
e
n
t
L
e
v
e
l
S
i
z
e
=
q
.
s
i
z
e
(
)
;
currentLevelSize = q.size();
currentLevelSize=q.size();得到当前层数的节点个数,然后利用一个for循环,从q取队头,pop,把队头对应的值插入到vec.back()的后一个位置,检查队头节点的左孩子不为空则入队列,检查队头结点的右孩子不为空则入队列,这里用back()方法就会得到数组的最后一个元素,也就是对应储存当前层的结点的
v
e
c
t
o
r
<
i
n
t
>
vector<int>
vector<int>,这样进行
c
u
r
r
e
n
t
L
e
v
e
l
S
i
z
e
currentLevelSize
currentLevelSize次,直到队列为空时结束.
从这里也可以看出,每次都会在for循环中把下一层的结点加入队尾,上一层的结点pop()出队列,所以每次for循环结束,队列的长度正是下一层的结点个数,并且一开始的时候,我们让root入队列,也正好对应了第一层的结点个数是1,不得不说是很巧妙的。
代码:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>> vec;
if (root == nullptr)
{
return vec;
}
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int currentLevelSize = q.size();
vector<int> t;
vec.push_back(t);
for (int i = 1; i <= currentLevelSize; i++)
{
TreeNode* tmp = q.front();
q.pop();
vec.back().push_back(tmp->val);
if (tmp->left != nullptr)
{
q.push(tmp->left);
}
if (tmp->right != nullptr)
{
q.push(tmp->right);
}
}
}
return vec;
}
};
时间复杂度:
O
(
n
)
O(n)
O(n),n是结点个数
空间复杂度:
O
(
l
)
O(l)
O(l),l是二叉树中一层中结点个数的最大值
二、利用前序遍历实现层序遍历
这个思想真的很巧妙,我们都知道前序遍历会先访问自己,再访问自己的左孩子,再访问自己的右孩子,我们只要在前序遍历的函数参数中加一个
d
e
p
t
h
depth
depth控制当前结点对应的深度(这里从0开始记深度)就可以了,进入前序遍历函数后,先检查当前结点是否为空,如果不为空,再检查当前深度
d
e
p
t
h
depth
depth是否大于等于
v
e
c
t
o
r
<
v
e
c
t
o
r
<
i
n
t
>
>
a
n
s
vector<vector<int>> ans
vector<vector<int>>ans的大小(或者改为
d
e
p
t
h
+
1
depth + 1
depth+1是否大于当前容器大小,这样更直观),如果是,那么说明当前层还没有来过,需要扩容;以上行动结束后,我们把当前结点的值插入到
a
n
s
[
d
e
p
t
h
]
ans[depth]
ans[depth]的最后一个元素,然后去遍历当前结点的左子树和右子树,只不过需要参数
d
e
p
t
h
depth
depth设置为
d
e
p
t
h
+
1
depth + 1
depth+1。
代码:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>> vec;
if (root == nullptr)
{
return vec;
}
preTraverse(root, 0, vec);
return vec;
}
void preTraverse(TreeNode* root, int depth,
vector<vector<int>>& ans)
{
if (root == nullptr)
{
return;
}
if (depth >= ans.size())
{
//如果深度大于数组的长度 说明这一层还没来过 需要扩容
ans.push_back(vector<int> {});
}
ans[depth].push_back(root->val);
preTraverse(root->left, depth + 1, ans);
preTraverse(root->right, depth + 1, ans);
}
}