算法题目:
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
通过次数294,770提交次数459,173
解题思路
第一感思维:遍历整棵树,那么我不知道哪个节点是哪一层的,我只能从左边遍历到底,然后在遍历右边(前序遍历)。那么怎么才能把树的数据封装到一个二维数组呢?
解决方案一(记录错误思维):
我遍历的时候加入index层级,每次遍历+1,那么是不是我就能每层都存储呢?答案是不行的,就算再加多少个index都无法准确的知道到底这个节点是第几层。
解决方案二
通过递归的方式来解决,每次递归把当前的层级号为入参,所以每次执行递归的时候我们就能知道你是第几层级,然后根据自己的层级号去res集合中get(index)对应的层级的集合List,把当前节点的值add到对应的层级的集合List当中,最后输出list;
话不多说直接上代码
public void runFunc2() {
TreeNode root = new TreeNode(3);
TreeNode root1 = new TreeNode(9);
TreeNode root2 = new TreeNode(20);
TreeNode root3 = new TreeNode(15);
TreeNode root4 = new TreeNode(7);
root.left = root1;
root.right = root2;
root.right.left = root3;
root.right.right = root4;
List<List<Integer>> res = new ArrayList<>();
TreeLevelTraversal.levelOrder2(root,res,1);
System.out.println(res);
}
public static void levelOrder2(TreeNode root, List<List<Integer>> list,int index) {
if(list.size()<index){
list.add(new ArrayList<Integer>());
}
list.get(index-1).add(root.val);
if(root.left != null)
levelOrder2(root.left, list,index+1);
if(root.right != null)
levelOrder2(root.right, list,index+1);
}
解决方案三
通过队列的方式来遍历(中序遍历),每次循环先把当前队列里数据的个数得到,遍历取出刚才每一个节点的值,最后把当前节点的子节点加入二维数组,直到最后list为空
代码实现:
public void runFunc() {
TreeNode root = new TreeNode(3);
TreeNode root1 = new TreeNode(9);
TreeNode root2 = new TreeNode(20);
TreeNode root3 = new TreeNode(15);
TreeNode root4 = new TreeNode(7);
root.left = root1;
root.right = root2;
root.right.left = root3;
root.right.right = root4;
System.out.println(TreeLevelTraversal.levelOrder(root));
}
public static List<List<Integer>> levelOrder(TreeNode root) {
if(root==null){
return new ArrayList<>();
}
List<List<Integer>> result = new ArrayList<>();
LinkedList<TreeNode> list = new LinkedList<>();
list.add(root);
List<Integer> root1 = new ArrayList<>();
while (!list.isEmpty()) {
int n = list.size();
root1 = new ArrayList<>();
for (int i = 0; i < n; i++) {
TreeNode treeNode = list.remove();
root1.add(treeNode.val);
if (treeNode.left != null) {
list.add(treeNode.left);
}
if (treeNode.right != null) {
list.add(treeNode.right);
}
}
result.add(root1);
root1 = null;
}
return result;
}
借用网络大神的逻辑图片
可以看到,此时队列中的结点是 3、4、5,分别来自第 1 层和第 2 层。这个时候,第 1 层的结点还没出完,第 2 层的结点就进来了,而且两层的结点在队列中紧挨在一起,我们无法区分队列中的结点来自哪一层。
因此,我们需要稍微修改一下代码,在每一层遍历开始前,先记录队列中的结点数量 n(也就是这一层的结点数量),然后一口气处理完这一层的 n 个结点。