链接
https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
难度: #中等
题目
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
提示:
- 节点总数 <= 1000
代码框架
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] levelOrder(TreeNode root) {
}
}
题目解析
这道题的本意就是,
二叉树的按层遍历,
二叉树最常见的三种遍历:
先序遍历,
中序遍历,
后序遍历,
这里按层遍历也比较常见,
本题的二叉树使用链表存储,
可以想到是使用广度优先遍历法,
广度优先遍历又分为两种实现方式:
递归实现和迭代循环实现。
解答思路1:
使用递归函数实现,
用辅助队列实现记录下一层需要遍历的节点,
如果没有下一层节点了,
则可以结束遍历。
解答思路2:
使用for循环实现,
用List队列记录下一层需要遍历的节点,
如果没有需要遍历的节点了,
则可以结束遍历,
然后按照List中的顺序返回数组。
注意List<Integer>转换为int[]原始类型数组的方法,
使用for循环:
List<TreeNode> list = new ArrayList<>();
int[] r = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
r[i] = list.get(i).val;
}
使用Stream流:
List<Integer> res = new ArrayList<>();
int[] r = res.stream().mapToInt(Integer::intValue).toArray();
使用for循环的性能远远优于Stream流,
这点要注意,
否则提交同样的代码,
使用Stream流的方式就无法达到执行用时超过100%。
解答思路3:
使用while循环实现,
用Queue队列记录下一层需要遍历的节点,
如果没有需要遍历的节点了,
则可以结束遍历。
测试用例
package edu.yuwen.sowrd.num32_I.solution;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import edu.yuwen.sowrd.entity.TreeNode;
import edu.yuwen.sowrd.num32_I.sol3.Solution;
public class SolutionTest {
/**
* 给定二叉树: [3,9,20,null,null,15,7]
* 3
* / \
*9 20
* / \
* 15 7
* 返回[3,9,20,15,7]
*/
@Test
public void testCase1() {
Solution solution = new Solution();
TreeNode node1 = new TreeNode(3);
TreeNode node2 = new TreeNode(9);
TreeNode node3 = new TreeNode(20);
TreeNode node4 = new TreeNode(15);
TreeNode node5 = new TreeNode(7);
node1.left = node2;
node1.right = node3;
node3.left = node4;
node3.right = node5;
TreeNode root = node1;
int[] res = solution.levelOrder(root);
int[] expected = { 3, 9, 20, 15, 7 };
Assertions.assertArrayEquals(expected, res);
}
}
解答1
package edu.yuwen.sowrd.num32_I.sol1;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import edu.yuwen.sowrd.entity.TreeNode;
public class Solution {
// 保存返回的结果
List<Integer> res = new ArrayList<>();
public int[] levelOrder(TreeNode root) {
if (root == null) {
return new int[0];
}
bfs(Collections.singletonList(root));
return res.stream().mapToInt(Integer::intValue).toArray();
}
/**
* bfs广度优先遍历,nodes都是同一层的节点
*/
private void bfs(List<TreeNode> nodes) {
List<TreeNode> newNodes = new ArrayList<>();
for (TreeNode node : nodes) {
// 打印同一层的所有节点
res.add(node.val);
// 保存下一层的所有节点
if (node.left != null) {
newNodes.add(node.left);
}
if (node.right != null) {
newNodes.add(node.right);
}
}
// 没有下一层节点,不需要继续广度遍历了
if (newNodes.size() == 0) {
return;
}
// 深度遍历下一层
bfs(newNodes);
}
}
解答2 推荐
package edu.yuwen.sowrd.num32_I.sol2;
import java.util.ArrayList;
import java.util.List;
import edu.yuwen.sowrd.entity.TreeNode;
public class Solution {
public int[] levelOrder(TreeNode root) {
if (root == null) {
return new int[0];
}
// 辅助队列记录每一层需要遍历的节点,配合end记录结束遍历
List<TreeNode> list = new ArrayList<>();
list.add(root);
int end = 1;
for (int i = 0; i < end; i++) {
TreeNode node = list.get(i);
if (node.left != null) {
list.add(node.left);
end++;
}
if (node.right != null) {
list.add(node.right);
end++;
}
}
int[] r = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
r[i] = list.get(i).val;
}
return r;
}
}
解答3
package edu.yuwen.sowrd.num32_I.sol3;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import edu.yuwen.sowrd.entity.TreeNode;
public class Solution {
public int[] levelOrder(TreeNode root) {
if (root == null) {
return new int[0];
}
// 保存返回的结果
List<Integer> res = new ArrayList<>();
// 辅助队列记录每一层需要遍历的节点
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
res.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
int[] r = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
r[i] = res.get(i);
}
return r;
}
}
网友评论