zoukankan      html  css  js  c++  java
  • 剑指Offer_#32_从上到下打印二叉树

    剑指Offer_#32_从上到下打印二叉树

    Contents

    这一题有三个变式,题目有细微差别.

    剑指Offer32-I:不分行从上到下打印二叉树

    题目

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

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

       3
       / 
      9  20
        /  
       15   7

    返回:

    [3,9,20,15,7]
    

    提示:
    节点总数 <= 1000

    思路分析

    这一题的遍历方式就是广度优先遍历(BFS),可以借助队列数据结构来实现。

    算法流程

    • 特殊情况:输入为null,直接返回空数组。
    • 初始化:初始化队列q,将root加入队列,初始化结果列表res
    • while循环:
      • 循环条件:队列不为空
      • 循环内容:
        • 取出队首元素cur
        • cur的值加入到res
        • cur的左右字节点加入队列q
    • 返回结果:将res转换为指定的int数组类型。

    解答

    class Solution {
        public int[] levelOrder(TreeNode root) {
            if(root == null) return new int[0];
            ArrayList<Integer> res= new ArrayList<>();
            //注意Queue的实例化方法,右边写的是LinkedList,因为LinkedList实现了Queue接口
            Queue<TreeNode> q = new LinkedList<>();
            q.offer(root);
            while(!q.isEmpty()){
                //取出队首元素
                TreeNode cur = q.poll();
                //取出的元素,加入到res列表
                res.add(cur.val);
                //继续将当前节点的左右子节点加入队列
                if(cur.left != null) q.offer(cur.left);
                if(cur.right != null) q.offer(cur.right);
            }
            //不能使用res.toArray()作为返回值,因为这样返回类型是Integer[],而非int[]
            //只能for循环赋值给int[]
            int[] intRes = new int[res.size()];
            for(int i = 0;i <= intRes.length - 1;i++){
                intRes[i] = res.get(i);
            }
            return intRes;
        }
    }

    剑指Offer32-II:分行从上到下打印二叉树

    题目

    从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
    例如:
    给定二叉树: [3,9,20,null,null,15,7],

        3
       / 
      9  20
        /  
       15   7

    返回其层次遍历结果:

    [
      [3],
      [9,20],
      [15,7]
    ]
     

    提示:
    节点总数 <= 1000

    思路分析

    和上一题相比,多了一个分行打印的要求。
    思路是,while循环当中再加入一层for循环,每个for循环打印一层的内容。
    关键在于如何控制for循环刚好打印完一层节点就结束?
    很巧妙的思路是:使用队列长度来初始化循环变量i,每次循环i递减。
    这样正好可以把一层的节点添加完。

    解答

    class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null) return res;
            Queue<TreeNode> q = new LinkedList<>();
            q.offer(root);
            while(!q.isEmpty()){
                List<Integer> tmp = new ArrayList<>();
                //ERROR:这样写不行,因为q.size()每一轮都在变化,应该把q.size()作为初始化
                //for(int i = 0;i <= q.size() - 1;i++){
                for(int i = q.size();i > 0;i--){
                    TreeNode cur = q.poll();
                    tmp.add(cur.val);
                    if(cur.left != null) q.offer(cur.left);
                    if(cur.right != null) q.offer(cur.right);
                }
                res.add(tmp);
            }
            return res;
        }
    }

    剑指Offer32-III:之字形从上到下打印二叉树

    题目

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

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

        3
       / 
      9  20
        /  
       15   7

    返回其层次遍历结果:

    [
      [3],
      [20,9],
      [15,7]
    ]

     

    提示:
    节点总数 <= 1000

    思路分析

    跟上一题基本一样,唯一的区别在于,需要根据层数的奇偶来控制打印顺序。只需要在向tmp添加元素的时候,加一个条件判断即可。

    解答

    class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            List<List<Integer>> res = new ArrayList<>();
            if (root == null) return res;
            Queue<TreeNode> q = new LinkedList<>();
            q.offer(root);
            while(!q.isEmpty()){
                List<Integer> tmp = new ArrayList<>();
                for(int i = q.size();i > 0;i--){
                    TreeNode cur = q.poll();
                    //相比上一题改动的地方
                    //当前已经打印出来的层数是偶数层,那么目前打印的是奇数层,应该按照从左到右的顺序
                    if(res.size() % 2 == 0) tmp.add(cur.val);
                    //当前已经打印出来的层数是奇数层,那么目前打印的是偶数层,应该按照从右到左的顺序
                    else tmp.add(0,cur.val);
                    if(cur.left != null) q.offer(cur.left);
                    if(cur.right != null) q.offer(cur.right);
                }
                res.add(tmp);
            }
            return res;
        }
    }
  • 相关阅读:
    【shell】两种字符串提取场景的实现
    【batch】批处理文件多参数处理和for循环字符串连接
    【Java】「深入理解Java虚拟机」学习笔记(4)- 类文件结构
    【Java】「深入理解Java虚拟机」学习笔记(2)- JVM内存区域
    【Java】「深入理解Java虚拟机」学习笔记(1)
    【Myeclipse】用Myeclipse10.5搭建C/C++开发环境
    【JDK】JDK模块化(1)-为什么要模块化
    【DOS】文件统计命令
    【java】转:Windows系统下面多个jdk版本切换
    【Web】servlet、filter和listener
  • 原文地址:https://www.cnblogs.com/Howfars/p/13256034.html
Copyright © 2011-2022 走看看