LeetCode每日一题 102. 二叉树的层序遍历

102. 二叉树的层序遍历

Tag Tree BFS

Difficulty Medium

Link 102. 二叉树的层序遍历

分析

本题要求按层遍历二叉树,也就是说每一层的元素作为一个数组存储到结果中。

1. 迭代

这道题我觉得迭代的思路比较好理解。

从根节点开始,用队列存储每一层的节点,将这些节点的值存到结果中

同时取这些节点的左右儿子放到一个新的队列中,

然后用新队列更新原队列,再次遍历,不断循环得到结果。

当然还可以优化一下,如果每次记录好当前层的节点数,那么就可以用for循环控制遍历的次数,不需要用一个额外的队列存下一行的节点了。这是迭代的第二个方法。

2. 递归

本题递归的重点就是节点的层数

按照层数向结果中添加该节点的值

然后继续取它的左右儿子

题解

1. 迭代
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
      	// 存储每一层的节点
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty() || root != null) {
          	// 每一层节点的值
            List<Integer> line = new ArrayList<>();
          	// 	存储下一行的节点
            Queue<TreeNode> tmp = new LinkedList<>();
          	// 遍历该行的每一个节点
            while (!q.isEmpty()) {
                root = q.poll();
              	// 当节点非空时,取出该节点的值,将其左右儿子存储到暂存队列中
                if (root != null) {
                    line.add(root.val);
                    tmp.offer(root.left);
                    tmp.offer(root.right);
                }
            }
          	// 暂存队列为空时,说明该层已经是最底层,没有下一层了。
            if (line.isEmpty()) break;
          	// 加入结果
            res.add(line);
          	// 将下一层的节点更新为这一层
            while (!tmp.isEmpty()) {
                q.offer(tmp.poll());
            }
        }
        return res;
    }

}
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> level = new ArrayList<>();
            // 存储当前层的节点数
            int len = q.size();
            // 遍历当前层的每一个节点
            for (int i=0; i<len; i++) {
                // 对于当前层的每一个节点,将值加入结果,并取其非空左右儿子加入队列
                // 由于提前确定了遍历的个数,所以后续加入的节点不会被遍历到,而是要到下一层的循环时才会被遍历
                root = q.poll();
                level.add(root.val);
                if (root.left != null) q.offer(root.left);
                if (root.right != null) q.offer(root.right);
            }
            res.add(level);
        }
        return res;
    }
}
复杂度分析:
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
2. 递归
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    private List<List<Integer>> res = new ArrayList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null) return res;
        dfs(root, 0);
        return res;
    }

    private void dfs(TreeNode root, int level) {
      	// res的大小表示它遍历到第几层
        if (res.size() == level) {
            res.add(new ArrayList<>());
        }
				// 按层添加值
        res.get(level).add(root.val);
        
        if (root.left != null) dfs(root.left, level+1);
        if (root.right != null) dfs(root.right, level+1);
    }
}
复杂度分析:
  • 时间复杂度: O ( n ) O(n) O(n)

  • 空间复杂度: O ( n ) O(n) O(n)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值