LeetCode102-二叉树的层序遍历
Posted Edwin Xu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode102-二叉树的层序遍历相关的知识,希望对你有一定的参考价值。
题目描述
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ 9 20
/ 15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
分析
先考虑只需要返回一个层序遍历结果而不用考虑到底是第几层。如上面只返回[3,9,20,15,7]
我们可以借助于一个队列Q:
首先把根元素放到Q中,while Q不为空时,一个个取出队首,将其不为null的子节点加入队列,直到队列为空。
用上面的例子,先把第一层3加入队列,然后3出队,加入子节点9,20,这是第二次;然后分别取出9,20,加入子节点15,7,这是第三次,取出15,7,他们没有子节点,没有元素入队,队为空,结束。
这个实现是比较简单的:
//层序 : 利用队列
public void layerTraversal(TreeNode root) {
Queue<TreeNode> q= new LinkedBlockingQueue<>();
TreeNode tmp ;
q.add(root);
while (q.size()>0){
tmp = q.poll();
System.out.print(tmp.val+" ");
if (tmp.left!=null)q.add(tmp.left);
if (tmp.right!=null)q.add(tmp.right);
}
}
实际上也可以利用数组,只不过稍微复杂点,原理一样。
//层序 : 利用数组
public void layerTraversal_iter_arr(TreeNode root){
TreeNode []treeNodes= new TreeNode[100];//缺点:难以预测大小,要么浪费空间,要么不足报错
int in=0,out=0;
treeNodes[in++]=root;
while (in>out){
if (treeNodes[out]!=null){
System.out.print(treeNodes[out].val+" ");
treeNodes[in++]=treeNodes[out].left;
treeNodes[in++]=treeNodes[out].right;
}
out++;
}
}
现在加需求了:需要考虑层次,即需要把不同层的分开。
我们如何在原来的基础上进行扩展了。
考虑前面使用队列的实现,一个队列存放了所有的元素,不能区分层次。如果使用两个队列存放,那么不同层不就可以交替使用,从而分开了吗?
比如有两个队列Q1、Q2,按上面的例子:
- 把root 3放到Q1
- Q1中3出队变空,子节点9,20放到Q2
- Q2出队变空,9,20的子节点15,7放到Q1
- Q1元素全部出队,没有子节点,两个队列都空了,程序结束。
那么现在就好实现了:
辅助双队列
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();//结构
LinkedList<TreeNode> q1 = new LinkedList<>();//Q1
LinkedList<TreeNode> q2 = new LinkedList<>();//Q2
LinkedList<TreeNode> cur,empty;//引用,分别指向当前使用的队列和空队列
TreeNode tmp;
if (root!=null)q1.add(root); //先把root加入Q1
while (!q1.isEmpty() || !q2.isEmpty()){//至少一个队列不为空
List<Integer> level = new LinkedList<>();
if (q1.isEmpty()){ //使cur指向正在使用的队列,empty指向即将用于存储的空队列
cur = q2;
empty = q1;
}else{
cur = q1;
empty= q2;
}
while (!cur.isEmpty()){//当前队列不为空,取出所有元素,把元素的非null子节点放到empty队列
tmp = cur.pop();
level.add(tmp.val);
if (tmp.left!=null)empty.add(tmp.left);
if (tmp.right!=null)empty.add(tmp.right);
}
res.add(level);
}
return res;
}
性能:
执行用时 :1 ms, 在所有 Java 提交中击败了91.30%的用户
内存消耗 :39.8 MB, 在所有 Java 提交中击败了5.71%的用户
空间开销有点大,可以考虑使用数组代替队列。
以上是关于LeetCode102-二叉树的层序遍历的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点# leetcode-102. 二叉树的层序遍历