一、迭代法
使用队列来记录层序遍历过程,借用队列先入先出特性,通过迭代实现层序遍历。
运行结果
执行结果:通过
执行用时 :1 ms, 在所有 Java 提交中击败了98.72%的用户
内存消耗 :36.5 MB, 在所有 Java 提交中击败了13.68%的用户
代码与注释
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Queue<TreeNode> queue = new LinkedList<>();
// 如果树为空,返回一个空Array
if (root == null) return ans;
// 把根节点加入到队列
queue.add(root);
// 记录当前是第几层
int levels = 0;
while (!queue.isEmpty())
{
// 新加一行
ans.add(new ArrayList<Integer>());
// 获取每层的数据长度
int len = queue.size();
// 遍历每层数据,将当前层数据存储,同时将下层数据加入队列
for (int i = 0; i < len; i++)
{
// 元素出队列
TreeNode node = queue.remove();
// 记录元素的值
ans.get(levels).add(node.val);
// 将下一层数据加入队列
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
levels ++;
}
return ans;
}
}
做题体会
- 时间复杂度:O(N),需要遍历每个节点。
- 空间复杂度:O(N+k),开了一个空间为N的ArrayList存储层序遍历结果,额外还开了一个队列记录每层的节点,最多节点一层的节点数为k。
- 最外层循环条件是队列不为空,通过读取队列的size,知道该层需要存储到结果数组中的节点数。巧妙之处在于,在for循环中将队列中的node弹出记录取值后,再将弹出节点的下一层的左右非空节点加入到队列中。for循环保证了该层的所有节点都能遍历到,进for循环前读取到的队列长度len,保证了存储的每层元素个数的正确性。levels记录了当前是第几层。如此实现了迭代遍历。
- 二叉树的层序遍历属于广度优先搜索(BFS)。
- 合理利用队列先入先出的性质,可以将某层元素从左至右全部入队,保证了出队的次序一定为从左至右,在出队过程中,可以将下一层的元素入队,从而实现了迭代。