“这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战”
题目描述
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
提示:
- 节点总数 <= 1000
题解
方法一:层序遍历 BFS
解题思路
- 按层打印:题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。BFS 通常借助 队列 的先入先出特性来实现。
- 每层打印到一行:将本层全部节点打印到一行,并将下一层全部节点加入队列,以此类推,即可分为多层打印。
算法流程:
-
特例处理:当根节点为空,则返回空列表
[]; -
初始化:打印结果列表
res = [],包含根节点的队列queue = [root]; -
BFS 循环:当队列
queue为空时跳出;-
新建一个临时列表
tmp,用于存储当前层打印结果; -
当前层打印循环:循环次数为当前节点数(即队列
queue长度);- 出队:队首元素出队,记为
node; - 打印:将
node.val添加至tmp尾部; - 添加子节点:若
node的左(右)子节点不为空,则将左(右)子节点加入队列(queue);
- 出队:队首元素出队,记为
-
将当前层结果
tmp添加入res。
-
-
返回值:返回打印结果列表
res即可。
代码
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()) {
List<Integer> tmp = new ArrayList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
res.add(tmp);
}
return res;
}
}
复杂度分析
- 时间复杂度 O(N) :N 为二叉树的节点数量,即 BFS 需循环 N 次。
- 空间复杂度 O(N) :最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点 同时 在
queue中,使用 O(N) 大小的额外空间。
个人理解
-
for 循环:
for(表达式1;表达式2;表达式3),表达式1 只会执行一次,所以可以用来分层,且初始值为queue.size(),在该循环中继续向队列中添加值也不影响分层结果。 -
arrayList 和 LinkedList 的区别:从下面关于 ArrayList 和 LinkedList 的区别可以看到,队列用 LinkedList 更好,存储每层数据不用频繁的插入和删除,直接用 ArrayList 即可。
- ArrayList 的实现是基于数组,LinkedList 的实现是基于双向链表
- 对于随机访问,ArrayList 优于 LinkedList
- 对于插入和删除操作,LinkedList 优于 ArrayList
- LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
-
ArrayList 的一些方法:
- 初始化:
ArrayList<Object> arrayList = new ArrayList<>(); - 大小:
arrayList.size(); - 添加:
arrayList.add(new Object()); - 判断对象是否在容器内(引用判断),返回 boolean 值:
arrayList.contains(new Object());
- 初始化:
-
LinkedList 的一些方法:
- 初始化:
LinkedList<String> linkedList = new LinkedList<>(); - 在链表后添加元素:
linkedList.add("first"); - 在链表头部插入元素:
linkedList.addFirst("addFirst"); - 移除链表第一个元素:
linkedList.remove(); - 移除链表最后一个元素:
linkedList.removeLast(); - 查询并移除第一个元素:
linkedList.poll(); - 获取第一个元素,但不移除:
linkedList.peek()
- 初始化:
题解来源
作者:jyd
链接:leetcode-cn.com/problems/co…
来源:力扣(LeetCode)
题目来源
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/co…
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。