LeetCode二叉树专题 (5) 二叉树的层次遍历 II

137 阅读2分钟

题目

给定一个二叉树,返回其节点值自底向上的层次遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)题目地址

解题思路

这道题是典型的层序遍历问题。可以先参考LeetCode每日一题 之 二叉树的行数打印

如果使用迭代,只要通过队列先进先出的结构即可。只是不同的是它要求每一层单独的输出,而不是把所有的节点放入一个数组里。这就要求我们判断是否进入了下一个层级,并输出到不同的数组中,怎么判断进入了下一个层级呢。可以先想一想🤔️ 有很多种方法可以判断进入了下一个层级,比如我们可以记录每一层的数量,一次遍历只遍历这些数量的节点,或者我们给每个通过null作为分界点,判断是否到了下一层。
如果使用递归的方法呢,我们需要怎么做,可以先想一想🤔️

递归方式

这里我们通过记录每一层的数量,只遍历这些数量的节点,就完成了层级的判断。

public List<List<Integer>> levelOrderBottom(TreeNode root) {
        LinkedList<List<Integer>> result = new LinkedList<>();
        if (root == null){
            return result;
        }
        //使用队列
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            List<Integer> oneLevel = new ArrayList<>();
            // 记录每一层的数量
            int count = queue.size();
            for (int i = 0; i < count; i++) {
                //把下一层所有的节点都遍历完成
                TreeNode node = queue.poll();
                oneLevel.add(node.val);
                if (node.left != null){
                    queue.add(node.left);
                }
                if (node.right != null){
                    queue.add(node.right);
                }
            }
            //因为要求从树的底层开始遍历,所以往前面插入
            result.addFirst(oneLevel);
        }
        return result;
    }

递归方式

怎么通过递归的方式完成层序遍历呢,传统的递归,我们都是深度优先的,显然和广度优先的层序遍历要求不符,但是我们是否可以在迭代的时候,记录每一层的层数,这样知道了每一层的层数,我们就可以插入到对应的数组中去了。

    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> lists = new ArrayList<>();
        func(lists, 0, root);
        for (int i = 0, j = lists.size() - 1; i < j; i++, j--) {
            List<Integer> temp = lists.get(i);
            lists.set(i, lists.get(j));
            lists.set(j, temp);
        }
        return lists;
    }

    private void func(List<List<Integer>> lists, int level, TreeNode root) {
        if (root == null) {
            return;
        }
        //根据层数,找到集合中的对应的数组插入
        if (lists.size() == level) {
            List<Integer> list = new ArrayList<>();
            list.add(root.val);
            lists.add(list);
        } else {
            lists.get(level).add(root.val);
        }
        func(lists, level + 1, root.left);
        func(lists, level + 1, root.right);
    }