三道题:
相同的部分:levelOrder层序遍历---->利用queue
不同的部分:第一题-从左到右,全部放入一个小组
第二题-从左到右,每层作为一个小组
第三题-z型,每层作为一个小组
剑指 Offer 32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
为什么用Queue来解决层序遍历?
Queue/Stack/tree
Queue特点:先进先出
Stack特点:先进后出
tree特点:获取上一层,才能得到下一层
解决方案:从queue中出来的一个node,就把其左右孩子,加入queue
第一题提要:从左到右,全部放入一个数组,一一用List来接收放入的值,转为int[]返回。
/**
* 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) {
if(root==null) return new int[]{};
//两种数据结构:Queue+ArrayList
Queue<TreeNode> queue=new LinkedList<>();//先进先出
ArrayList<Integer> list=new ArrayList<>();//接收结果
//核心方案:queue中取出一个元素,再把其左右孩子加入queue
queue.add(root);
while(!queue.isEmpty()){//终止条件为所有东西都拿出了,这个队列为空
TreeNode node = queue.remove();//queue取出一个元素
list.add(node.val);//将节点值加入list
if(node.left!=null) queue.add(node.left);//左孩子不空,加入到queue
if(node.right!=null) queue.add(node.right);//右孩子
}
//把ArrayList类型转换为int[]数组
int[] res=new int[list.size()];
for(int i=0;i<list.size();i++){
res[i]=list.get(i);
}
return res;
}
}
剑指 Offer 32 - II. 从上到下打印二叉树
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
第二题提要:每层都放入一个List<Integer>通过for循环queue.size()次来分辨每一层。(通过size将其分为多个组,每个for循环完成一层遍历,将每一层数字添加到ArrayList<>中,最后将每个ArrayList<>加到res,最后返回)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//与第一题返回值不同,边界条件不同
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
//两种数据结构:Queue+ArrayList
Queue<TreeNode> queue=new LinkedList<>();//先进先出
ArrayList<Integer> list=new ArrayList<>();//接收结果
//核心方案:queue中取出一个元素,再把其左右孩子加入queue
queue.add(root);
while(!queue.isEmpty()){//终止条件为所有东西都拿出了,这个队列为空
//用queue.size来分出每一层,每一个for循环就是不同的层
ArrayList<Integer> temp=new ArrayList<>();
int size=queue.size();//一定要先获得,防止fast fall
for(int i=0;i<size;i++){
TreeNode node = queue.remove();//queue取出一个元素
temp.add(node.val);//将节点值加入list
if(node.left!=null) queue.add(node.left);//左孩子不空,加入到queue
if(node.right!=null) queue.add(node.right);//右孩子
}
res.add(temp);//将temp,ArrayList<Integer>结构加到List<list<Integer>>结构中。
}
return res;
}
}
剑指 Offer 32 - IlI. 从上到下打印二叉树
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
第三题提要:z型,通过list中的尾部追加->头部插入。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//与第一题返回值不同,边界条件不同
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
//两种数据结构:Queue+ArrayList
Queue<TreeNode> queue=new LinkedList<>();//先进先出
ArrayList<Integer> list=new ArrayList<>();//接收结果
//核心方案:queue中取出一个元素,再把其左右孩子加入queue
queue.add(root);
while(!queue.isEmpty()){//终止条件为所有东西都拿出了,这个队列为空
//用queue.size来分出每一层,每一个for循环就是不同的层
/*这里上一题中用的是ArrayList,这道题由于从头部插入的话性能很差,
*每次插入都要将全部元素向后复制,所以使用LinkedList<>
*LinkedList<>是双向链表,从头部插入只需添加一个指针
*/
List<Integer> temp=new LinkedList<>();
int size=queue.size();//一定要先获得,防止fast fall
for(int i=0;i<size;i++){
TreeNode node = queue.remove();//queue取出一个元素
temp.add(node.val);//将节点值加入list
if(node.left!=null) queue.add(node.left);//左孩子不空,加入到queue
if(node.right!=null) queue.add(node.right);//右孩子
}
res.add(temp);//将temp,ArrayList<Integer>结构加到List<list<Integer>>结构中。
}
return res;
}
}