剑指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;
    }
}
posted @ 2020-07-06 17:47  Howfar's  阅读(135)  评论(0编辑  收藏  举报