题目描述
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
各种解法
1. 递归实现
import java.util.*;
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//用来存放最终结果
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(root==null) { // 为空的情况,直接返回
return res;
}
// 深度优先搜索
dfs(1,root,res); // 两个参数,当前处于的层数
return res;
}
void dfs(int index,TreeNode root, List<List<Integer>> res) {
if(res.size()<index) { // 说明进入是这一层的第一个元素
res.add(new ArrayList<Integer>());
}
// 统一的操作,把这个元素放到自己所在层的list中
res.get(index-1).add(root.val);
//递归的处理左子树,右子树,同时将层数index+1
if(root.left!=null) {
dfs(index+1, root.left, res);
}
if(root.right!=null) {
dfs(index+1, root.right, res);
}
}
}
解题思路
- 深度优先搜索,从根节点向下搜索,层数+1;遇到是当前层数的第一个节点,那么要新创建一个list并存入结果。
- 因为深度优先,所以每一层的靠前的元素肯定是先出现的。整体的出现顺序是从上到下,从左到右地被存入结果中。
2. 广度优先搜索
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
// 队列用来记录当前还没有处理的节点
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
// 这一层的节点个数
int levellength = queue.size();
for(int i=0; i<levellength; i++){
TreeNode node = queue.poll();
level.add(node.val);
// 把节点取出来,计入到list中,并且看看有没有左右子节点
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
res.add(level);
}
return res;
}
}
解题思路
- 用一个队列来存储当前层的节点。
- 把当前层的节点拿出来,看看他有没有左右子节点,有的话就把他加到队列中。
- 等到当前层的节点遍历完后,开一个新的list,遍历下一层的节点
变形题
1. 之形遍历
- 和上面的不同就是,现在需要用的是双端队列,并且附带一个遍历方向的标志位
- 当前层的元素遍历的过程中,把当前层的左右子节点加入队列,作为下一层做准备。当前层元素遍历结束,就从另一个方向把下一层的节点拿出来进行遍历。
- 以此类推。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
// 队列用来记录当前还没有处理的节点
Deque<TreeNode> queue = new LinkedList<>();
boolean direction = true;
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
// 这一层的节点个数
int levellength = queue.size();
// 把节点取出来,计入到list中,并且看看有没有左右子节点
for(int i=0; i<levellength; i++){
// 根据方向来分别处理
if(direction){
TreeNode node = queue.pollFirst();
level.add(node.val);
if(node.left != null){
queue.offerLast(node.left);
}
if(node.right != null){
queue.offerLast(node.right);
}
} else{
TreeNode node = queue.pollLast();
level.add(node.val);
if(node.left != null){
queue.offerFirst(node.left);
}
if(node.right != null){
queue.offerFirst(node.right);
}
}
}
direction = !direction;
res.add(level);
}
return res;
}
}