队列的使用以及泛型思考[二叉树的层序遍历]
队列的使用以及泛型思考
https://leetcode.cn/problems/binary-tree-level-order-traversal/description/?envType=study-plan-v2&envId=top-100-liked
LeetCode102层序遍历
这题在思想上没什么要讲的,就是二叉树的层序遍历,那与之对应的是二叉树的深序遍历.
层序遍历,是一层一层遍历,从上到下,从左到右.
深序遍历:LDR,DLR,LRD
那此时其实可以看出来,层序遍历就有点像广度优先遍历(BFS),而且题目当中还有一个非常重要的信息
先进先出
这不就是队列嘛.
所以我们知道了,这道题目从思想上考的是层序遍历,技术上考的是队列的理解与使用.
考点
- 层序遍历
- 队列
- 泛型
为什么,或者说从哪里看出来要考泛型呢?
从输出这里,题目中最后要求输出的数据组织成这样的形式.
那实际上从外到里就是这个样子的
List<List<TreeNode>>
那么问题来了,我们将这棵树放入队列之后,要怎么去区分当前要出队列的元素是数组的哪一层呢?
去找个变量在元素入队列的时候记录一下.
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> result=new ArrayList<>();if(root==null){return new ArrayList<>();}Queue<TreeNode> queue=new LinkedList<>();queue.offer(root); // 将根节点放入到队列中while(!queue.isEmpty()){List<Integer> tem=new ArrayList<>();int levelSize=queue.size(); // 记录这棵树每一层有多少个元素for(int i=0;i<levelSize;i++){TreeNode t = new TreeNode();t=queue.poll(); // 出队列if(t.left!=null){ // 判断该节点有无左节点,如果有,将该左节点入队列queue.offer(t.left);}if(t.right!=null){ // 判断该节点有无右节点,如果有,将该右节点入队列queue.offer(t.right);}tem.add(t.val); // 将该节点的val值放入List<Integer> 中}result.add(tem); // for循环结束,意味着这棵树中的一层处理结束,此时将List<Integer>放入List<List<Integer>>中}return result; // while循环结束后,树的每一层处理结束,返回结果}
}
注意:这里while循环的判断条件
!queue.isEmpty()
queue在这里永远不为null,所以不能使用
queue!=null
来进行判断
因为我们在while上方手动new了Queue对象
Queue<TreeNode> queue=new LinkedList<>();
所以queue永远不为null,因为queue已经指向了一个对象,但是我们在这里本意是判断queue中有没有值.
所以使用
queue.isEmpty() 来进行判断.
总结
这道题目,个人认为考察的是如何从问题中提炼出或者说能想到这个问题适用于什么数据结构.
三步法
问题识别 → 方法选择 → 结果构造
第一步:识别问题类型(读懂输入 + 输出 + 限制)
把题读成一句话:“我有 __,要求 __,输出 __”
以这题为例:
- 输入是一棵二叉树
- 要求是“从上到下按层遍历”
- 输出是二维数组,表示每一层的节点值
问题关键词:[树结构]、[一层一层]、[顺序输出]
很自然联想到:队列 + 广度优先搜索(BFS)
第二步:匹配数据结构和算法模板(靠关键词触发)
建立一个“关键词 → 方法映射表”来形成条件反射。
关键词 | 方法/数据结构提示 |
---|---|
“一层一层”、“最短路径”、“先到先处理” | BFS + 队列 |
“一条路走到底”、“所有路径”、“遍历所有可能” | DFS + 递归/回溯 |
“查找最小/最大/中位数”、“前 k 个” | 优先队列(堆) |
“有序”、“重复”、“快速定位”、“区间” | 二分查找、滑动窗口、哈希表等 |
“连续”、“最大和”、“子数组” | 动态规划/前缀和 |
“树结构”、“层次”、“节点值关系” | 树 + BFS / DFS / 递归 |
第三步:构造结果格式(读懂返回值)
看清楚你要的输出,是“一个数”?“一个列表”?“二维结构”?“节点”?“布尔值”?
输出类型 | 说明 |
---|---|
int | 最值问题:最大最小,路径长短,最短路径 |
List<Integer> | 一维序列:所有结果、一条路径、某一层节点 |
List<List<Integer>> | 二维:通常是层序结构、组合、分层、分组结果 |
boolean | 判定型问题,如“是否有路径”、“是否存在” |
TreeNode | 返回节点或构造新树结构问题 |
举个实战流程(这题)总结一下:
- 题目描述:二叉树按层输出 → “树结构 + 一层一层” = BFS
- 方法选择:广度优先搜索 + 队列
- 数据结构:队列用于存放下一层的节点
- 输出结构:每层是一个 list,所有层放到总 list 中 →
List<List<Integer>>