107. 二叉树的层次遍历 II

107. 二叉树的层次遍历 II (简单)

题目描述

给定一个二叉树, 返回自底向上的层次遍历, 并返回一个二维数组.

比如说,给你的二叉树是:

     1
   /   \
  2     4
       / \
      8  16

它的逆层序遍历结果是:

[
 [8, 16],
 [2, 4],
 [1],
]

本题和第102题-二叉树的层次遍历类似, 只不过遍历顺序不同.

题目解析

解法一: DFS

102 题DFS贴过来看一下。

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

private void DFS(TreeNode root, int level, List<List<Integer>> ans) {
    if(root == null){
        return;
    }
    //当前层数还没有元素,先 new 一个空的列表
    if(ans.size()<=level){
        ans.add(new ArrayList<>());
    }
    //当前值加入
    ans.get(level).add(root.val);

    DFS(root.left,level+1,ans);
    DFS(root.right,level+1,ans);
}
Copy

之前我们根据 level 得到数组的位置,然后添加。

ans.get(level).add(root.val);

ans    [] [] [] [] [].
index  0  1  2  3  4
level  0  1  2  3  4
       ------------>
index = 0 + level

现在 level 是逆过来存的
ans    [] [] [] [] [].
index  0  1  2  3  4
level  4  3  2  1  0
       <------------
index = 4 - level

4 就是 ans 的末尾下标,就是 ans.size() - 1
所以代码变为
ans.get(ans.size() - 1 - level).add(root.val);
Copy

此外还有句代码要改。

if(ans.size()<=level){
    ans.add(new ArrayList<>());
}
在添加当前 level 的第一个元素的时候,首先添加一个空列表到 ans 中
假设当前 level = 2,ans 中只添加了 level 是 01 的元素
ans    [3] [9] 
index   0   1  
level   1   0  
因为 level 是从右往左增加的,所以空列表要到 ans 的头部
ans     [] [3] [9] 
index   0   1   2
level   2   1   0  
所以代码改成下边的样子
 ans.add(0new ArrayList<>());
Copy

综上,只要改了这两处就可以了。

// DFS方式
public void DFS(TreeNode root, List<List<Integer>> ans, int level) {
    if (root == null) {
        return;
    }
    if (ans.size() <= level) {
        // 这部分需要将空数组存到数组的头部, 因为是反着存的
        ans.add(0, new ArrayList<>());
    }
    // 关键部分, 使用下标来反着存
    ans.get(ans.size()-1-level).add(root.val);
    DFS(root.left, ans, level + 1);
    DFS(root.right, ans, level + 1);
}
public List<List<Integer>> levelOrderRecursive(TreeNode root) {
    List<List<Integer>> ans = new ArrayList<>();
    if (root == null) {
        return ans;
    }
    DFS(root, ans, 0);
    return ans;
}

解法二: BFS

相比于正常的遍历, 只需要改一行代码即可.

// BFS方式(队列)
public List<List<Integer>> levelOrderIterative(TreeNode root) {
    List<List<Integer>> ans = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();
    if (root == null) {
        return ans;
    }
    queue.offer(root);
    int cnt = 0;
    while (!queue.isEmpty()) {
        int size = queue.size();
        List<Integer> subList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            TreeNode s = queue.poll();
            subList.add(s.val);
            if (s.left != null) queue.offer(s.left);
            if (s.right != null) queue.offer(s.right);
        }
        // 这里就是变动的部分, 改为插入到头部即可.
        ans.add(0, subList);
    }
    return ans;
}

综合

本题和第102题-二叉树的层次遍历类似, 只需要在上一题的基础上, 寻找到levelindex之间的对应关系即可.

此外, 因为我们在头部添加元素, 所以用链表会好一些, 如果用ArrayList, 插入需要整体后移, 时间会增加一些.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值