Ⅰ
面试题32 - I. 从上到下打印二叉树https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
想法:二叉树的层次遍历,借助队列实现,首先将二叉树的头节点放入,再从队列中依次取出节点,若该节点有左右孩子,再将其依次入队.
代码:
/**
* 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[0];
List<Integer> level= new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
//将根节点入队
queue.add(root);
//层次遍历二叉树
while(!queue.isEmpty()){
//取队首元素
TreeNode head=queue.poll();
//加入列表
level.add(head.val);
// System.out.println(head.val);
if(head.left!=null)
queue.add(head.left);
if(head.right!=null)
queue.add(head.right);
}
//将列表转为数组
int[] res = new int[level.size()];
for(int i = 0;i<level.size();i++){
res[i] = level.get(i);
}
return res;
}
}
结果:
Ⅱ.
剑指 Offer 32 - II. 从上到下打印二叉树 IIhttps://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
想法:此题与1类似,但需要每一层单独打印,可以将"每一批一起入队的节点"一起打印,即打印子表时,遍历打印"当前"队列长度的所有元素.
代码:
/**
* 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<TreeNode> queue = new LinkedList<>();
//将根节点入队
queue.add(root);
//层次遍历二叉树
while(!queue.isEmpty()){
List<Integer> level= new ArrayList<>();
//遍历"此时"队列中的所有元素并"打印"
for(int i=queue.size();i>0;i--){
//取队首元素
TreeNode head=queue.poll();
//加入列表
level.add(head.val);
// System.out.println(head.val);
if(head.left!=null)
queue.add(head.left);
if(head.right!=null)
queue.add(head.right);
}
// System.out.println();
res.add(level);
}
return res;
}
}
结果:
Ⅲ.
剑指 Offer 32 - III. 从上到下打印二叉树 IIIhttps://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/
想法: 改题目与Ⅱ相似,考虑使用两个队列,一个存从左到右,一个存从右到左,遍历每层时判断该层序号的奇偶,若为奇数则打印从左到右,否则打印从右到左.
代码:
/**
* 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<TreeNode> queueLR = new LinkedList<>();
//从右往左
Queue<TreeNode> queueRL = new LinkedList<>();
//将根节点入队
queueLR.add(root);
queueRL.add(root);
//true代表奇数层:从左往右,false代表偶数层:从右往左
Boolean levelNum=true;
//层次遍历二叉树
while(!queueLR.isEmpty()){
List<Integer> level= new ArrayList<>();
for(int i=queueLR.size();i>0;i--){
//取队首元素
TreeNode headLR=queueLR.poll();
TreeNode headRL=queueRL.poll();
//判断奇偶
if(levelNum)
level.add(headLR.val);
else
level.add(headRL.val);
//从左往右 先放左孩子,后放右孩子
if(headLR.left!=null)
queueLR.add(headLR.left);
if(headLR.right!=null)
queueLR.add(headLR.right);
//从右往左 先放右孩子,后放左孩子
if(headRL.right!=null)
queueRL.add(headRL.right);
if(headRL.left!=null)
queueRL.add(headRL.left);
}
levelNum=!levelNum;
res.add(level);
}
return res;
}
}
想法二:使用双端队列tmp
代码:
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()) {
//tmp 作双端队列使用
LinkedList<Integer> tmp = new LinkedList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
//通过结果列表的size判断
if(res.size() % 2 == 0)
// size为偶数,则当前为奇数层 -> 队列尾部添加,从左往右
tmp.addLast(node.val);
else
// size为奇数,则当前为偶数层 -> 队列头部添加,从右往左
tmp.addFirst(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
res.add(tmp);
}
return res;
}
}
结果: