听不少大佬建议过——力扣刷题要从树开始 !
因为可以建立起套路化的思路~ 另外就是锻炼好递归的思想
所以 我们从树开始~
本专题采用 前面提到的 “兔系刷题法”
不求钻研多种解法 只求快速见题型快速刷题!
另外 力扣评论区里看见的——
树的题目写不出来,多背几个模版就行。
前中后序、广度深度遍历、路径和、深度,直径,这些全部背下来。
感觉很有道理!多背些多理解些套路嘛!
本次刷题笔记中有两道题 相比上一篇二叉树遍历的基础 难度有所提升
但还是属于比较简单的题 可以帮助我们更好地获得递归的套路~
这两道题是我超爱的两题!循序渐进der~
使用广度优先搜索的思想进行求解
剑指 Offer 32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
这道题难度到了中等
但是其实并没有达到其他题型的中等题那样难缠、、可以说是比较迷惑的一个难度评级了
本题要绕的一个弯是——
初始化的用于存储结果的列表res 是用的
List
!res = new ArrayList ();
但是在代码最开头是public int[] levelOrder(TreeNode root)
如果直接返回res会出现泛型错误(这个具体俺还没研究明白 emmm 大佬们有什么想法的话求帮助啊!)
在最后需要将列表转换成数组 这时候再输出就不会编译错误了~
queue
为空时跳出node
node.val
添加到结果列表 tmp
尾部queue
中添加子节点(当前遍历到的 node
节点的子节点)用个循环就ok辽~
迭代法
使用广度优先搜索BFS算法
class Solution {
public int[] levelOrder(TreeNode root) {
// 01 特例处理
if (root == null){
return new int[0];
}
// 02 初始化队列 结果列表
Queue<TreeNode> queue = new LinkedList<TreeNode>();//初始化队列 用于按顺序存放遍历到的每层的节点
List<Integer> res = new ArrayList<Integer>();//初始化存结果的列表(但是这不是)
queue.add(root);//先把根节点加到队列中————层序遍历第一个打印的节点
//03 广度优先搜索
while(!queue.isEmpty()){
TreeNode node = queue.poll();//1 节点出队
res.add(node.val);//将节点按顺序加入结果列表中
if (node.left != null) queue.add(node.left);//如果下一层还有节点的话 将其入队
if (node.right != null) queue.add(node.right);//下一层没节点的话 说明已经没有需要加入队列的节点了~
}
// 04 把列表转换成数组
// 可以使用jdk8的新特性 stream流
// return list.stream().mapToInt(Integer::intValue).toArray();
// 但是上面这个速度会慢一些!
int[] ans = new int[res.size()];//这个数组才符合输出条件~
for (int i = 0; i <= res.size() - 1; i ++){
ans[i] = res.get(i);//获取队列中的值 要使用.get(i)
}
return ans;
}
}
和上一题差不多意思~
102. 二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
输入:二叉树:[3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
输出:
[
[3],
[9,20],
[15,7]
]
可以看到 区别就是
本题结果是个二维数组 每一行的结果都被单独单独打印出来了~
在树的遍历中 使用了 BFS(Breadth-First-Search) 也就是广度优先搜索算法解决
【1】特例处理 判断边界条件——根为空
【2】初始化 创建 存放每层节点的队列queue 结果列表res
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList();
别忘了根节点入队 queue.add(root);
【3】进行BFS广度优先搜索
{1}新建一个临时列表 用于存储当前层的打印结果
List<Integer> temp = new ArrayList<>();
{2}进行循环 把队列中的节点值 node.val
按序添加到临时列表temp
的尾部 & 把加入列表节点的子节点加入到队列中
for(int i = 0; i < levelNum; i++){
//3 把队列中的元素加到临时列表中
TreeNode node = queue.poll();//节点入队
temp.add(node.val);//加入当层结果中
// 4 结束每一个的元素的添加后 都要看一下它是否有下一层
// 如果有 就入到队列中排队去~
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
//5 每层节点按序排好后加入到 结果二维数组 中
res.add(temp);
【4】返回最终结果 二维数组 res
~
注释贼齐全 跟着注释往下走 保看懂~
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//01 判断边界条件
if(root == null){
return new ArrayList<>();
}
//02 队列
Queue<TreeNode> queue = new LinkedList<>();//存放每层的节点值
List<List<Integer>> res = new ArrayList();//创建二维数组 结果
//根节点入队
queue.add(root);
//03 进行BFS广度优先搜索
while(!queue.isEmpty()){
int levelNum = queue.size();//1 记录每层的节点数量
List <Integer> temp = new ArrayList<>();//2 新建一个临时列表 存每层节点值
for(int i = 0; i < levelNum; i++){
//3 把队列中的元素加到临时列表中
TreeNode node = queue.poll();//节点出队
temp.add(node.val);//加入当层结果中
// 4 结束每一个的元素的添加后 都要看一下它是否有下一层
// 如果有 就入到队列中排队去~
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
//5 每层节点按序排好后加入到 结果二维数组中
res.add(temp);
}
// 04 BFS结束 输出最终结果
return res;
}
}