• 二叉树层次遍历(递归版)


    题目:

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

    例如:
    给定二叉树 [3,9,20,null,null,15,7],

        3
       /
      9  20
        / 
       15   7

    返回其自底向上的层次遍历为:

    [
      [15,7],
      [9,20],
      [3]
    ]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    分析:

    看到这个题目我第一反应是递归,不过貌似好像大概还有挺多不同的解法。本篇文章记录一下我的递归思路,其他的算法留待日后学习。

    力扣上给出的空方法模板的返回值为List<List<Integer>>,结合题干可知,每一层的节点数值应按顺序存入一个集合中,所有的节点集合也要保存在一个集合中。

    那么问题来了,对于方法而言,二叉树的层数是未知的,那么应该创建多少个节点集合呢?可以先用递归来求一下二叉树的最长路径,但是,考虑到时间复杂度和空间复杂度的话,我否定了这个想法。

    最终我选择在递归中创建节点集合,当访问到每一层的最左节点时,创建该层的节点集合,方法就是通过一个int值来记录二叉树的层数,当到达二叉树的第一层(顶层)时,int为0,此时集合内尚未创建顶层节点集合,事实上这个时候集合内没有任何节点集合,所以它的size为0,以此类推,我们分析可知,当集合的size小于等于当前层数记录(也就是int值)的时候,需要创建当前层的节点集合。

    当递归访问下一层时,需将当前层数记录+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>> levelOrderBottom(TreeNode root) {
            List<List<Integer>> lists = new ArrayList<>();
            getVal(root, lists, 0);
            Collections.reverse(lists);
            return lists;
        }
    
        public void getVal(TreeNode root, List<List<Integer>> lists, int curr) {
            if (root == null) {
                return;
            }
            if (lists.size() <= curr) {
                lists.add(new ArrayList<>());
            }
            lists.get(curr).add(root.val);
            getVal(root.left, lists, curr + 1);
            getVal(root.right, lists, curr + 1);
        }
    }

    本篇小结:

    其实,这些二叉树、递归什么的概念之前一直是知道的,但也仅限于知道而已,可以说没有真正的好好练习和应用过,最近学习算法的时候有几次用到,没想到还挺香~

    不过在做这道算法题的时候,还是小小的纠结了一下,我当时的疑惑是递归方法会按照我预想的顺序执行吗?

    假设现在有一个二层的二叉树:

        6
       /
      7  8

    我希望的执行顺序是先将6添加进集合,再将7添加进集合,最后将8添加进集合。

    在递归方法中首先将6添加进集合,然后依次调用了访问节点7和节点8的递归,虽然代码是有先后次序,但是方法执行时会按照次序执行吗?

    在实践中发现,是我想多了,顿时觉得心情舒畅,看来以后可以更加愉快的使用递归了!

    第二个收获就是又发现了一个宝藏方法Collections.reverse(),将集合倒序重排,爱了爱了。

  • 相关阅读:
    调用网易有道词典api
    函数设计
    参数2
    新浪微博API使用初步介绍——解决回调地址的问题
    参数关键点和return返回多个(伪多个)值问题
    函数基本理论
    一个值得思考的例子
    Beego基础学习(五)Golang原生sql操作Mysql数据库增删改查(基于Beego下测试)
    Golang利用select实现超时机制
    Golang利用select和普通函数分别实现斐波那契数列
  • 原文地址:https://www.cnblogs.com/wxdmw/p/13277719.html
Copyright © 2020-2023  润新知