arraylist 后往前遍历_507,BFS和DFS解二叉树的层序遍历 II

b5c37085b21b2757c41e23afbf38c3ff.png

Standing for right when it is unpopular is a true test of moral character. 

站在不受欢迎但却正确的一边,才是真正的道德考验。

问题描述

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

例如:

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

    3   / \  9  20    /  \   15   7

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

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

BFS解决

这题类似于二叉树的BFS打印,就是一层一层的打印,一般情况下对于二叉树我们都是从上往下打印,但这题是从下往上打印。直接从下往上不太好操作,可以换种思路,因为题目要求的结果是从下往上就可以了,并没有要求打印的过程。

1e973679435cbf0684f28ee2385a3a14.png

我们依然可以从上往下打印,只不过打印每一层的时候,结果都要插到列表的最前面,这样最终结果和从下往上打印的结果就完全一样了。

 1public List> levelOrderBottom(TreeNode root) { 2    //边界条件判断 3    if (root == null) 4        return new ArrayList<>(); 5    //队列 6    Queue queue = new LinkedList<>(); 7    List> res = new ArrayList<>(); 8    //根节点入队 9    queue.add(root);10    //如果队列不为空就继续循环11    while (!queue.isEmpty()) {12        //BFS打印,levelCount表示的是每层的结点数13        int levelCount = queue.size();14        //subList存储的是每层的结点值15        List subList = new ArrayList<>();16        for (int i = 0; i 17            //出队18            TreeNode node = queue.poll();19            subList.add(node.val);20            //左右子节点如果不为空就加入到队列中21            if (node.left != null)22                queue.add(node.left);23            if (node.right != null)24                queue.add(node.right);25        }26        //把每层的结点值存储在res中,插入到最前面27        //(类似于从下往上打印,关键点在这)28        res.add(0, subList);29    }30    return res;31}

DFS解决

在前面讲373,数据结构-6,树的时候提到过二叉树的BFS和DFS,其中DFS是一直往下走的,到叶子节点然后再返回。对于这道题我们从根节点往下走的时候,每一层都会有一个集合list,用来存放当前层的节点值,如果当前层的list没有创建,就先创建。原理也比较简单,来看下代码

 1public List<List> levelOrderBottom(TreeNode root) { 2    List<List> res = new ArrayList<>(); 3    helper(res, root, 0); 4    return res; 5} 6 7public void helper(List<List> list, TreeNode root, int level) { 8    //边界条件判断 9    if (root == null)10        return;11    //如果level等于list的长度,说明到下一层了,12    //并且下一层的ArrayList还没有初始化,我们要13    //先初始化一个ArrayList,然后放进去。14    if (level == list.size()) {15        list.add(0, new ArrayList<>());16    }17    //这里就相当于从后往前打印了18    list.get(list.size() - level - 1).add(root.val);19    //当前节点访问完之后,再使用递归的方式分别访问当前节点的左右子节点20    helper(list, root.left, level + 1);21    helper(list, root.right, level + 1);22}

总结

只要明白二叉树的BFS遍历,这题就很容易解决,虽然这题结果是从下往上,但我们只需要在每层节点值存储的时候修改一下位置即可。

8495a778344c74795b4f08b5f67a1365.gif

●470,DFS和BFS解合并二叉树

●464,BFS和DFS解二叉树的所有路径

●453,DFS和BFS解求根到叶子节点数字之和

●417,BFS和DFS两种方式求岛屿的最大面积

截止到目前我已经写了500多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有800多页,大家可以在公众号中回复关键字“pdf”即可获取下载链接。

如果觉得有用就点个"赞"吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值