前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指offer | 面试题25:从上到下打印二叉树

剑指offer | 面试题25:从上到下打印二叉树

作者头像
千羽
发布2021-12-29 13:22:35
8430
发布2021-12-29 13:22:35
举报
文章被收录于专栏:程序员千羽

死磕算法系列文章

  1. 干货 | 手撕十大经典排序算法
  2. 剑指offer | 认识面试
  3. 剑指offer | 面试题2:实现Singleton模式
  4. 剑指offer | 面试题3:二维数组的查找
  5. 剑指offer | 面试题4:替换空格
  6. 剑指offer | 面试题5:从尾到头打印链表
  7. 剑指offer | 面试题6:重建二叉树
  8. 剑指offer | 面试题7:用两个栈实现队列
  9. 剑指offer | 面试题8:旋转数组的最小数字
  10. 剑指offer | 面试题9:斐波那契数列
  11. 剑指offer | 面试题10:青蛙跳台阶问题
  12. 剑指offer | 面试题11:矩阵覆盖
  13. 剑指offer | 面试题12:二进制中1的个数
  14. 剑指offer | 面试题13:数值的整数次方
  15. 剑指offer | 面试题14:打印从1到最大的n位数
  16. 剑指offer | 面试题15:删除链表的节点
  17. 剑指offer | 面试题16:将数组中的奇数放在偶数前
  18. 剑指offer | 面试题17:链表中倒数第k个节点
  19. 剑指offer | 面试题18:反转链表
  20. 剑指offer | 面试题19:合并两个有序链表
  21. 剑指offer | 面试题20:判断二叉树A中是否包含子树B
  22. 剑指offer | 面试题21:二叉树的镜像
  23. 剑指offer | 面试题22:顺时针打印矩阵
  24. 剑指offer | 面试题23:包含min函数的栈
  25. 剑指offer | 面试题24:栈的压入、弹出序列

Leetcode :

  • I:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof
  • II:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof
  • III:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof

GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_25_levelOrder/Solution.java

剑指 Offer 25. 从上到下打印二叉树 I

题目描述 :从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:给定二叉树: [3,9,20,null,null,15,7],

代码语言:javascript
复制
        3
       / \
     9  20
    /  \
   15   7

返回:

代码语言:javascript
复制
[3,9,20,15,7]

提示:节点总数 <= 1000

解题思路:

  • 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。
  • BFS 通常借助 队列 的先入先出特性来实现。
算法流程:
  1. 特例处理: 当树的根节点为空,则直接返回空列表 []
  2. 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root]
  3. BFS 循环: 当队列 queue 为空时跳出;
    1. 出队: 队首元素出队,记为 node
    2. 打印:node.val 添加至列表 tmp 尾部;
    3. 添加子节点:node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue
  4. 返回值: 返回打印结果列表 res 即可。
复杂度分析:
  • 时间复杂度 O(N): N为二叉树的节点数量,即 BFS 需循环 N次。
  • 空间复杂度 O(N) :最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。
代码语言:javascript
复制
package com.nateshao.sword_offer.topic_25_levelOrder;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
 * @date Created by 邵桐杰 on 2021/11/29 14:57
 * @微信公众号 程序员千羽
 * @个人网站 www.nateshao.cn
 * @博客 https://nateshao.gitee.io
 * @GitHub https://github.com/nateshao
 * @Gitee https://gitee.com/nateshao
 * Description: 从上到下打印二叉树 思路:利用队列(链表)辅助实现。
 *
 * add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
 * remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
 * element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
 * offer 添加一个元素并返回true 如果队列已满,则返回false
 * poll 移除并返问队列头部的元素 如果队列为空,则返回null
 * peek 返回队列头部的元素 如果队列为空,则返回null
 * put 添加一个元素 如果队列满,则阻塞
 * take 移除并返回队列头部的元素 如果队列为空,则阻塞
 */
public class Solution {

    /**
     *  队列
     *
     * @param root
     * @return
     */
    public int[] levelOrder(TreeNode root) {
        if (root == null) return new int[0];//空树则返回空数组
        ArrayList<Integer> list = new ArrayList<>();// 申请一个动态数组 ArrayList 动态添加节点值
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);// 根结点先入队
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();// 取出当前队首元素
            list.add(node.val);
            if (node.left != null) queue.offer(node.left);// 左子节点入队
            if (node.right != null) queue.offer(node.right);// 右子节点入队
        }
        // 将 ArrayList 转为 int数组并返回
        int[] res = new int[list.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    /************ 递归 *************/
    public ArrayList<Integer> PrintFromTopToBottom2(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (root == null) {
            return list;
        }
        list.add(root.val);
        levelOrder(root, list);
        return list;
    }
    public void levelOrder(TreeNode root, ArrayList<Integer> list) {
        if (root == null) {
            return;
        }
        if (root.left != null) {
            list.add(root.left.val);
        }
        if (root.right != null) {
            list.add(root.right.val);
        }
        levelOrder(root.left, list);
        levelOrder(root.right, list);
    }

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
}

剑指 Offer 25 - II. 从上到下打印二叉树 II

题目描述 :从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

“例如:给定二叉树: [3,9,20,null,null,15,7],

代码语言:javascript
复制
     3
    / \
   9  20
 /  \
15   7

返回其层次遍历结果:

代码语言:javascript
复制
[
  [3],
  [9,20],
  [15,7]
]
代码语言:javascript
复制
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()) {
            List<Integer> tmp = new ArrayList<>();
            for(int i = queue.size(); i > 0; i--) {
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
}

剑指 Offer 25 - III. 从上到下打印二叉树 III

题目描述: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如: 给定二叉树: [3,9,20,null,null,15,7],

代码语言:javascript
复制
    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

代码语言:javascript
复制
[
  [3],
  [20,9],
  [15,7]
]
代码语言:javascript
复制
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) deque.add(root);
        while(!deque.isEmpty()) {
            // 打印奇数层
            List<Integer> tmp = new ArrayList<>();
            for(int i = deque.size(); i > 0; i--) {
                // 从左向右打印
                TreeNode node = deque.removeFirst();
                tmp.add(node.val);
                // 先左后右加入下层节点
                if(node.left != null) deque.addLast(node.left);
                if(node.right != null) deque.addLast(node.right);
            }
            res.add(tmp);
            if(deque.isEmpty()) break; // 若为空则提前跳出
            // 打印偶数层
            tmp = new ArrayList<>();
            for(int i = deque.size(); i > 0; i--) {
                // 从右向左打印
                TreeNode node = deque.removeLast();
                tmp.add(node.val);
                // 先右后左加入下层节点
                if(node.right != null) deque.addFirst(node.right);
                if(node.left != null) deque.addFirst(node.left);
            }
            res.add(tmp);
        }
        return res;
    }
}

参考连接:

  1. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/solution/mian-shi-ti-32-i-cong-shang-dao-xia-da-yin-er-ch-4
  2. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5
  3. https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 千羽的编程时光 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 剑指 Offer 25. 从上到下打印二叉树 I
  • 剑指 Offer 25 - II. 从上到下打印二叉树 II
  • 剑指 Offer 25 - III. 从上到下打印二叉树 III
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档