Day 14: 从上到下打印二叉树
一棵圣诞树记作根节点为 root
的二叉树,节点值为该位置装饰彩灯的颜色编号。请按照从 左 到 右 的顺序返回每一层彩灯编号。
示例 1:
输入:root = [8,17,21,18,null,null,6] 输出:[8,17,21,18,6]
LCR 149. 彩灯装饰记录 I - 力扣(LeetCode)
经典树的层次遍历
/**
* 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 int[] decorateRecord(TreeNode root) {
if (root == null) {
return new int[0]; // 如果根节点为 null,返回空数组
}
Queue<TreeNode> queue = new ArrayDeque<>();
TreeNode p = root;
queue.offer(root);
List<Integer> resultList = new ArrayList<>(); // 使用 List 存储结果
while(!queue.isEmpty()){
if (p.left != null) {
queue.offer(p.left);
}
if (p.right != null) {
queue.offer(p.right);
}
queue.poll();
resultList.add(p.val);
p = queue.peek();
}
int[] result = new int[resultList.size()];
for (int i = 0; i < resultList.size(); i++) {
result[i] = resultList.get(i);
}
return result;
}
}
拓展题目
LCR 150. 彩灯装饰记录 II - 力扣(LeetCode)
这个题目就不是简单的层次遍历了,需要记录层数了。
/**
* 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>> decorateRecord(TreeNode root) {
List<List<Integer>> resultList = new ArrayList<>();
if (root == null) {
return resultList; // 如果根节点为 null,返回空数组
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> result = new ArrayList<>(); // 存储每层的节点
int levelSize = queue.size(); // 当前层的节点个数
for(int i = 0; i < levelSize; i++){
TreeNode p = queue.poll(); // 取出队头节点
result.add(p.val); // 将节点值加入当前层的结果
if (p.left != null) {
queue.offer(p.left);
}
if (p.right != null) {
queue.offer(p.right);
}
}
resultList.add(result);
}
return resultList;
}
}
这个题目是层次遍历的另一种写法,我建议记这种,因为涉及需要跟层数相关的时候好操作。
为什么这样能保证在队列里的元素就是一层的元素呢。因为我们在上一次循环的过程中就已经保证下一层所有节点加入到队列了。我们在for循环中把上一层的节点全部去除,那么在每一次while循环开始前队列的长度就是每层的长度。
拓展题目
LCR 151. 彩灯装饰记录 III - 力扣(LeetCode)
这个题目跟上面那个差不多,就是要之字形输出。
/**
* 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>> decorateRecord(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result; // 如果根节点为 null,返回空数组
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int level = 1;
while (!queue.isEmpty()) {
int levelSize = queue.size(); // 当前层的节点
List<Integer> currentLevel = new ArrayList<>(); // 存储当前层的节点值
// 遍历当前层的所有节点
for (int i = 0; i < levelSize; i++) {
TreeNode currentNode = queue.poll(); // 取出队头节点
currentLevel.add(currentNode.val); // 将节点值加入当前层的结果
// 将左右子节点加入队列
if (currentNode.left != null) {
queue.offer(currentNode.left);
}
if (currentNode.right != null) {
queue.offer(currentNode.right);
}
}
// 将当前层的结果加入最终结果
if(level % 2 != 0){
result.add(currentLevel);
} else{
Stack<Integer> stack = new Stack<>();
for(int num : currentLevel){
stack.add(num);
}
List<Integer> currentLevel2 = new ArrayList<>(); // 存储当前层的节点值逆向
while(!stack.isEmpty()){
currentLevel2.add(stack.pop());
}
result.add(currentLevel2);
}
level++;
}
return result;
}
}
或者我们直接用LinkedList双端队列,两边都可以进出,只用在偶数的时候插到另一边就行:
class Solution {
public List<List<Integer>> decorateRecord(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()) {
LinkedList<Integer> tmp = new LinkedList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
if(res.size() % 2 == 0) tmp.addLast(node.val);
else 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;
}
}