当前位置: 首页 > news >正文

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;
    }
}

相关文章:

  • Android启动速度优化
  • STM32单片机FreeRTOS系统11 系统时钟节拍和时间管理,定时器组
  • 基于小波分析法的行波测距判断故障及定位故障Matlab仿真
  • std::ranges::views::split, lazy_split, std::ranges::split_view, lazy_split_view
  • vs2022用git插件重置--删除更改(--hard)后恢复删除的内容
  • 深入解析Go语言Channel:源码剖析与并发读写机制
  • 高级定时器的解码器模式
  • upload-labs-靶场(1-19关)通关攻略
  • python-leetcode 50.岛屿数量
  • 颤抖:quiver,shiver,tremble的区别
  • 火绒终端安全管理系统V2.0--分层防御之行为拦截层
  • Benewake(北醒) 快速实现TF-NOVA IIC接口与电脑通信的操作说明
  • 电子文档安全管理系统 V6.0 resources/backup存在任意文件下载漏洞(DVB-2025-8794)
  • 数据结构与算法:归并排序
  • AIM-T500绝缘监测仪:实时监测,确保IT系统绝缘安全-安科瑞 蒋静
  • 2025-03-12 学习记录--C/C++-PTA 习题10-11 有序表的增删改查操作
  • 论数组去重之高效方法
  • ai讲angular rxjs
  • [023-01-40].第40节:组件应用 - OpenFeign与 Sentinel 集成实现fallback服务降级
  • C++ 中的 static_assert 编译期断言使用
  • 多条跨境铁路加速推进,谁是下一个“超级枢纽”?
  • 尊严的代价:新加坡福利体系下的价值困境
  • 支持企业增强战略敏捷更好发展,上海市领导密集走访外贸外资企业
  • 人民日报访巴西总统卢拉:“巴中关系正处于历史最好时期”
  • 署名文章:从宏观调控看中国经济基本面
  • 游戏论|暴君无道,吊民伐罪——《苏丹的游戏》中的政治