【Java实现超级高频面试题,字节半年16次】剑指Offer32.2——从上到下打印二叉树(二)(LeetCode102:二叉树的层序遍历)思路分享

在这里插入图片描述
同学们,我把《剑指Offer》中所有“树”标签的习题及思路整理出来了,对照学习效果更佳:


题目分析:层序遍历、广度优先(BFS)一般都是借助队列的!!!

这道题建议参考二叉树的深度,其中的第二种解法——层序遍历,用队列的思想巧妙地实现。

不同于上一道题从上到下打印二叉树,这道题要求每一行输出一个数组,而不是一个一维数组,需要变成二维数组

所以问题的难点就来了:

怎么确定哪些元素是来自同一行呢??

接下来介绍两种方法,能够很巧妙地确定元素的行所属:

方法一:两个辅助队列

这个方法就是二叉树的深度中使用的方法,借助两个队列,两个List集合,能够很好地完成任务,但是效率略低。

算法步骤:

  1. 判断根节点是否为空(常规判断,注意按题意返回值)
  2. 创建辅助队列(queuehelp)和集合(reslist
  3. 进入循环,循环条件是queue不为空
  4. 在增强for中,节点出queue,值加入list
  5. 判断是否有左右子节点,再加入help
  6. 当for循环结束,说明一行结束了,此时把list加入res
  7. help赋值给queue,同时等待下一轮循环help重置
  8. 因此直到所有点遍历完,queue才会空

代码如下:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root==null) return new ArrayList<>();

        List<List<Integer>> res=new ArrayList<>();
        List<Integer> list=null;

        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        Queue<TreeNode> help=null;

        while(!queue.isEmpty()) {
            help=new LinkedList<>();
            list=new ArrayList<>();
            for(TreeNode node : queue) {
                //加入大集合
                list.add(node.val);
                if(node.left != null) help.add(node.left);
                if(node.right != null) help.add(node.right);
            }
            res.add(list);
            queue=help;
        }
        return res;
    }
}

方法二:一个辅助队列+ 循环

看了大神的题解,这方法真实太巧妙了!!!!!膜拜膜拜

最巧妙地点在于,通过for循环的次数,控制了每一行的元素同一轮出队列

算法步骤和上面基本类似,只是控制每行的思路不同:

  1. 不需要第二个help队列,而是每次都加入queue
  2. 循环前先获取queue的长度,在循环中再添加,因此,后添加的并不会被遍历,只能等到下一轮(就这里最巧妙!!!)
  3. 一轮结束,赋值给res

代码如下:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null) {
            return new ArrayList<>();
        }
        List<List<Integer>> res=new ArrayList<>();
        
        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()) {
            List<Integer> list=new ArrayList<>();
            for(int i=queue.size();i>0;i--) {
                TreeNode node=queue.poll();
                list.add(node.val);
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(list);
        }
        return res;
    }
}

复杂度分析:

  • 时间复杂度:O(N),同样道理,遍历树中所有节点
  • 空间复杂度:O(N),需要队列来辅助
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值