每日一恋 - LeetCode 102 & 107. 二叉树的层次遍历

102. 二叉树的层次遍历

解法一

用队列实现
步骤:

  1. 当队列不为空时,计算队列中元素的个数,作为本层循环的次数。
  2. 依次取出队列中指定个数的节点,加入到subList中,同时将其左右孩子加入到队列中。
  3. 重复1、2直到队列里没有元素。
 public List<List<Integer>> levelOrder(TreeNode root) {

    Queue<TreeNode> queue = new LinkedList<>();
    List<List<Integer>> list = new LinkedList<>();

    if (root == null)
        return list;

    queue.offer(root);
    while (!queue.isEmpty()) {
        int levelSize = queue.size();
        List<Integer> subList = new LinkedList<>();
        for (int i = 0 ; i < levelSize ; i ++) {
            TreeNode node = queue.poll();
            if ( node.left != null ) queue.offer(node.left);
            if ( node.right != null ) queue.offer(node.right);
            subList.add(node.val);
        }
        list.add(subList);
    }
    return list;
}

解法二

递归法,每层递归只访问其中一个节点,若当前层数(从0开始)大于等于结果集中的层数(从1开始),则创建一个新集合加入到双重集合中,并将当前节点的值放在对应层的集合中。每次递归遍历左右孩子并将层数+1。

public List<List<Integer>> levelOrder(TreeNode root) {
   List<List<Integer>> res = new ArrayList<>();
    levelHelper(res, root, 0);
    return res;
}

public void levelHelper(List<List<Integer>> res, TreeNode root, int height) {
    if (root == null) return;
    if (height >= res.size())
        res.add(new LinkedList<>());
    res.get(height).add(root.val);
    levelHelper(res, root.left, height + 1);
    levelHelper(res, root.right, height + 1);
}

107. 二叉树的层次遍历 II

这道题给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)。说白了,就是层的顺序反转,每层中的节点顺序不变。

因此下面两个解法与上一题非常相似,只是在加入子集合的时候,不是按照顺序加入,而是倒序加入。

解法一

public List<List<Integer>> levelOrderBottom(TreeNode root) {

    Queue<TreeNode> queue = new LinkedList<>();
    List<List<Integer>> list = new LinkedList<>();

    if (root == null)
        return list;

    queue.offer(root);
    while (!queue.isEmpty()) {
        int levelSize = queue.size();
        List<Integer> subList = new LinkedList<>();
        for (int i = 0 ; i < levelSize ; i ++) {
            TreeNode node = queue.poll();
            if ( node.left != null ) queue.offer(node.left);
            if ( node.right != null ) queue.offer(node.right);
            subList.add((Integer) node.e);
        }
        list.add(0, subList); // 反转,每次都往头部插入
    }
    return list;
}

解法二

public List<List<Integer>> levelOrderBottom(TreeNode root) {
    List<List<Integer>> wrapList = new LinkedList<List<Integer>>();
    levelMaker(wrapList, root, 0);
    return wrapList;
}

// DFS
public void levelMaker(List<List<Integer>> list, TreeNode<Integer> root, int level) {
    if(root == null) return;
    if(level >= list.size()) 
        list.add(0, new LinkedList<Integer>());
    list.get(list.size()-level-1).add(root.e); // 反转
    levelMaker(list, root.left, level+1);
    levelMaker(list, root.right, level+1);
}

更多关于二叉树的前序遍历、中序遍历、后序遍历的总结,请看每日一恋 - LeetCode 144 & 94 & 145. 二叉树的前序遍历、中序遍历、后序遍历

本文是我参考了网上的资料和加上自己的理解总结的,如果有什么不对的地方非常欢迎大家的指正。

猜你喜欢

转载自blog.csdn.net/smartnijun/article/details/81808022