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

Leetcode 103: 二叉树的锯齿形层序遍历

Leetcode 103: 二叉树的锯齿形层序遍历

问题描述:
给定一个二叉树,返回其节点值的锯齿形层序遍历(即第一层从左到右,第二层从右到左,第三层从左到右,依此类推)。


适合面试的解法:广度优先搜索 + 双端队列

解法特点:

  1. 广度优先搜索(BFS): 通过层序遍历按层处理节点,确保节点遍历的层次性。
  2. 双端队列(Deque): 通过双端队列控制节点值的加入顺序,实现锯齿形效果。
    • 从左到右:直接将节点值加入队列的尾部。
    • 从右到左:将节点值插入队列的头部。
  3. 用 BFS 控制每层的遍历顺序,用双端队列处理结果的锯齿形排序。

适合面试的原因:

  • 时间复杂度 (O(n)),空间复杂度 (O(n)),效率高且易于实现。
  • 展现了灵活的队列操作,是树和 BFS 综合应用的常见场景。

解法思路

核心步骤:
  1. 初始化:

    • 使用队列 Queue<TreeNode> 来管理每层的节点。
    • 定义标志变量 leftToRight 用来判断当前层的遍历方向。
  2. 层序遍历:

    • 遍历每一层节点:
      • 如果 leftToRight = true,将节点值加入到当前层结果的尾部;
      • 如果 leftToRight = false,将节点值插入到当前层结果的头部。
    • 将当前层的结果加入最终结果列表。
  3. 翻转方向:

    • 每处理完一层后,翻转 leftToRight,切换从左到右或从右到左的方向。

代码模板

方法:广度优先搜索 + 双端队列
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result; // 如果树为空,直接返回空列表

        Queue<TreeNode> queue = new LinkedList<>(); // BFS 队列
        queue.offer(root);
        boolean leftToRight = true; // 初始遍历方向是从左到右

        while (!queue.isEmpty()) {
            int levelSize = queue.size();
            Deque<Integer> levelList = new LinkedList<>(); // 双端队列存储当前层的节点值

            // 遍历当前层所有节点
            for (int i = 0; i < levelSize; i++) {
                TreeNode currentNode = queue.poll();

                if (leftToRight) {
                    levelList.addLast(currentNode.val); // 从左到右:添加到尾部
                } else {
                    levelList.addFirst(currentNode.val); // 从右到左:添加到头部
                }

                // 加入下一层的节点
                if (currentNode.left != null) queue.offer(currentNode.left);
                if (currentNode.right != null) queue.offer(currentNode.right);
            }

            // 将当前层的结果加入最终结果
            result.add(new ArrayList<>(levelList));

            // 翻转方向
            leftToRight = !leftToRight;
        }

        return result;
    }
}

代码详细注释

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        // 定义最终结果列表
        List<List<Integer>> result = new ArrayList<>();
        
        // 特殊边界条件:如果树为空,直接返回
        if (root == null) return result;

        // 初始化 BFS 队列和方向标记
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root); // 将根节点加入 BFS 队列
        boolean leftToRight = true; // 起始从左到右遍历

        // BFS 遍历二叉树的每一层
        while (!queue.isEmpty()) {
            int levelSize = queue.size(); // 当前层的节点数
            Deque<Integer> levelList = new LinkedList<>(); // 使用双端队列保存当前层结果

            for (int i = 0; i < levelSize; i++) {
                TreeNode currentNode = queue.poll(); // 从队列中取出当前节点

                // 根据遍历方向将节点值添加到双端队列
                if (leftToRight) {
                    levelList.addLast(currentNode.val); // 从左到右时,添加到队尾
                } else {
                    levelList.addFirst(currentNode.val); // 从右到左时,添加到队头
                }

                // 将当前节点的左右孩子加入队列
                if (currentNode.left != null) {
                    queue.offer(currentNode.left);
                }
                if (currentNode.right != null) {
                    queue.offer(currentNode.right);
                }
            }

            // 将双端队列的结果转换为列表,加入最终结果
            result.add(new ArrayList<>(levelList));

            // 翻转方向
            leftToRight = !leftToRight;
        }

        return result; // 返回最终结果
    }
}

复杂度分析

时间复杂度:
  • 每个节点仅被访问一次,时间复杂度为 (O(n)),其中 (n) 是树中节点总数。
空间复杂度:
  • BFS 队列最多存储一层的节点,最坏情况是 (O(n))。
  • 使用双端队列临时存储每层结果,复杂度为 (O(w)),其中 (w) 是二叉树的最大宽度。
    综合空间复杂度为 (O(n))。

测试用例

示例 1:
输入:
    3
   / \
  9  20
    /  \
   15   7

输出:
[
  [3],
  [20,9],
  [15,7]
]

示例 2:
输入:
    1
   / \
  2   3
 / \
4   5

输出:
[
  [1],
  [3,2],
  [4,5]
]

示例 3:
输入: null
输出: []

如何快速 AC(面试技巧)

1. 清晰解释 BFS 对二叉树的层序遍历

  • BFS 利用队列按层层处理节点,巧妙地分离层次关系。
  • 在片段中添加「左右翻转」是实现锯齿形遍历的核心技巧。

2. 灵活使用双端队列

  • 明确说明为什么使用双端队列:
    • 从左到右时添加到队尾;
    • 从右到左时插入到队头。

3. 时间和空间复杂度分析

  • 说明 BFS 遍历节点的线性开销 (O(n)),无多余操作,非常高效。

4. 特殊情况处理

  • 空树(根节点为 null)时,应返回空结果。

总结

适合面试的解法:广度优先搜索 + 双端队列

  • 女人拆分思路:利用 BFS 分层处理节点,用双端队列处理锯齿效果。
  • 时间复杂度 (O(n))、空间复杂度 (O(n)),是最优解决方案。

如何快速 AC:

  1. 清晰实现 BFS,按层处理树节点
  2. 双端队列解决锯齿效果,结合方向标记灵活转换;
  3. 完整测试,涵盖空树和各种复杂结构树。

这种高效解法逻辑清晰,非常适合面试场景!

相关文章:

  • 算法日记33:14届蓝桥C++B冶炼金属(二分答案)
  • 10个实用IntelliJ IDEA插件
  • es 修改索引模板分词类型
  • 归并排序:分治哲学的完美演绎与时空平衡的艺术
  • 蓝桥杯算法——铠甲合体
  • FPGA有关HDMI的一些知识,程序源自bilibi正点原子
  • Spring Boot 3.0核心特性解读
  • vue 安装包时报错 Error: not found: python2
  • C++ 内存序在多线程中的使用
  • 扫雷雷雷雷雷【水文勿三】
  • 能简述一下动态 SQL 的执行原理吗
  • 信号与系统第二章学习(六)
  • 利用Python爬虫按图搜索1688商品(拍立淘)
  • 安装好pycharm后,双击pycharm,出现“无法找到入口”,怎么办?
  • 第3章:启动界面与主界面设计
  • 解锁前端表单数据的秘密旅程:从后端到用户选择!✨
  • 线程池项目优化
  • mapbox高阶,结合threejs(threebox)实现立体三维飞线图
  • 时尚创意品牌海报徽标设计无衬线英文字体安装包 Scribles – A Brush Font
  • Python 面向对象高级编程-定制类
  • erp系统界面/首页关键词优化公司
  • 网站建设 南昌/网站seo视频
  • 建设游戏网站/长沙靠谱seo优化价格
  • 泰安公司网站开发/简单的个人主页网站制作
  • 做付费网站/国外搜索引擎大全
  • 做公司网站比较好的/政府免费培训 面点班