描述
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
返回:
[
[3],
[9, 20],
[15, 7]
]
思路
广度优先遍历(BFS)。
在之前做的题目中,涉及到前序,中序,后序遍历都是深度优先遍历(DFS),通常会通过递归的方式来实现DFS,优点是不用手动维护栈,代码简洁,易于记忆(三种遍历只用调整代码顺序即可)。
而BFS的实现则通常是通过迭代的方式,而不是递归。代码相对复杂,但是,有一些情况是递归不好实现的,比如说本题,用BFS才是正确的。
BFS的基本实现是基于队列(Queue)的,
void bfs(TreeNode root) {Deque<TreeNode> queue = new ArrayDeque<>();List<Integer> result = new ArrayList<>();// 首先,入队root结点,入队总从最后入queue.addLast(root);while(!queue.isEmpty()) {// 出队,出队总从第一个出TreeNode temp = queue.pollFirst();// 添加到结果数组中result.add(temp.val);// 入队左结点if (temp.left != null) {queue.addLast(temp.left);}// 入队右结点if (temp.right != null) {queue.addLast(temp.right);}}}
在通过BFS遍历以后,result数组是一个一维数组,这与本题不相符,本题需要区分每一层。
因此只需要加一个size来记住每一层的结点数即可,修改后的代码如下:
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> result = new ArrayList<>();// 记得判断空树,否则直接调用bfs会报错,空指针异常。if (root == null) {return result;}bfs(root, result);return result;}private void bfs(TreeNode root, List<List<Integer>> result) {Deque<TreeNode> queue = new ArrayDeque<>();// 首先,入队root结点,入队总从最后入queue.addLast(root);while(!queue.isEmpty()) {List<Integer> level = new ArrayList<>();// 保存sizeint size = queue.size();// 遍历次数为size次for (int i = 0; i < size; i++) {// 出队,出队总从第一个出TreeNode temp = queue.pollFirst();// 添加到结果数组中level.add(temp.val);// 入队左结点if (temp.left != null) {queue.addLast(temp.left);}// 入队右结点if (temp.right != null) {queue.addLast(temp.right);}}result.add(level);}}}
