二叉树的层序遍历[中等]

优质博文:IT-BLOG-CN

一、题目

给你二叉树的根节点root,返回其节点值的 层序遍历 。(即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:
输入:root = [1]
输出:[[1]]

示例 3:
输入:root = []
输出:[]

树中节点数目在范围[0, 2000]
-1000 <= Node.val <= 1000

二、代码

广度优先搜索: 我们可以用广度优先搜索解决这个问题。我们可以想到最朴素的方法是用一个二元组(node, level)来表示状态,它表示某个节点和它所在的层数,每个新进队列的节点的level值都是父亲节点的level值加一。最后根据每个点的level对点进行分类,分类的时候我们可以利用哈希表,维护一个以level为键,对应节点值组成的数组为值,广度优先搜索结束以后按键level从小到大取出所有值,组成答案返回即可。

考虑如何优化空间开销:如何不用哈希映射,并且只用一个变量node表示状态,实现这个功能呢?

我们可以用一种巧妙的方法修改广度优先搜索:
1、首先根元素入队
2、当队列不为空的时候:求当前队列的长度si;依次从队列中取si个元素进行拓展,然后进入下一次迭代;

它和普通广度优先搜索的区别在于,普通广度优先搜索每次只取一个元素拓展,而这里每次取si个元素。在上述过程中的第i次迭代就得到了二叉树的第i层的si个元素。

为什么这么做是对的呢?我们观察这个算法,可以归纳出这样的循环不变式:第i次迭代前,队列中的所有元素就是第i层的所有元素,并且按照从左向右的顺序排列。证明它的三条性质(你也可以把它理解成数学归纳法):
【1】初始化: i=1的时候,队列里面只有root,是唯一的层数为1的元素,因为只有一个元素,所以也显然满足「从左向右排列」;
【2】保持: 如果i=k时性质成立,即第k轮中出队sk的元素是第k层的所有元素,并且顺序从左到右。因为对树进行广度优先搜索的时候由低k层的点拓展出的点一定也只能是k+1层的点,并且k+1层的点只能由第k层的点拓展到,所以由这sk个点能拓展到下一层所有的sk+1个点。又因为队列的先进先出(FIFO)特性,既然第k层的点的出队顺序是从左向右,那么第k+1层也一定是从左向右。至此,我们已经可以通过数学归纳法证明循环不变式的正确性。
【3】终止: 因为该循环不变式是正确的,所以按照这个方法迭代之后每次迭代得到的也就是当前层的层次遍历结果。至此,我们证明了算法是正确的。

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

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
   
            List<Integer> level = new ArrayList<Integer>();
            int currentLevelSize = queue.size();
            for (int i = 1; i <= currentLevelSize; ++i) {
   
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null) {
   
                    queue.offer(node.left);
                }
                if (node.right != null) {
   
                    queue.offer(node.right);
                }
            }
            ret.add(level);
        }
        
        return ret;
    }
}

时间复杂度: 每个点进队出队各一次,故渐进时间复杂度为O(n)
空间复杂度: 队列中元素的个数不超过n个,故渐进空间复杂度为O(n)

相关推荐

  1. 102.

    2023-12-09 07:04:06       30 阅读
  2. 107. II

    2023-12-09 07:04:06       34 阅读
  3. 102.

    2023-12-09 07:04:06       30 阅读
  4. leetcode 102.

    2023-12-09 07:04:06       29 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-09 07:04:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-09 07:04:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-09 07:04:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-09 07:04:06       18 阅读

热门阅读

  1. 有关CSS选择器

    2023-12-09 07:04:06       39 阅读
  2. C++_对C数据类型的扩展

    2023-12-09 07:04:06       28 阅读
  3. ChatGPT的常识

    2023-12-09 07:04:06       42 阅读
  4. 蓝桥杯ACwing习题

    2023-12-09 07:04:06       33 阅读
  5. 美国Linux服务器的iptables防火墙介绍

    2023-12-09 07:04:06       40 阅读
  6. iClient3D 加载天地图服务

    2023-12-09 07:04:06       28 阅读
  7. MySQL七 | 存储引擎

    2023-12-09 07:04:06       40 阅读
  8. Visual Studio 2015 中 FFmpeg 开发环境的搭建

    2023-12-09 07:04:06       34 阅读
  9. 排序算法——冒泡排序

    2023-12-09 07:04:06       41 阅读
  10. P5743 【深基7.习8】猴子吃桃

    2023-12-09 07:04:06       36 阅读
  11. prometheus服务发现之consul

    2023-12-09 07:04:06       44 阅读
  12. Flink之JDBCSink连接MySQL

    2023-12-09 07:04:06       32 阅读