二叉树的层平均值、 找树左下角的值(力扣第637题、513题)

题目:

  给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

示例:

输入:
    3
   / \
  9  20
    /  \
   15   7
输出:[3, 14.5, 11]
解释:
第 0 层的平均值是 3 ,  第1层是 14.5 , 第2层是 11 。因此返回 [3, 14.5, 11] 。

提示:

  节点值的范围在32位有符号整数范围内。

分析

  求二叉树每一层所有节点的平均值,那么既要得到每一层节点值得累加和,也要得到每一层得节点总数,所以可以采用二叉树的层次遍历的方式,二叉树的层次遍历借助了队列这个数据结构,该数据结构的特点是先进先出,当遍历每一层的第一个节点的时候,此时队列中的存储的是二叉树的当前层的所有节点,根节点所在层是第一层,只有一个节点,它出队以后可以将它的所有子节点存入队中,访问第二层的第一个结点的时候,此时队列存储的正是第二层的所有节点,可以先获取队列中节点数量依次得到该层的节点总数,再进行for循环,将该层的节点全部访问出队,同时将这些节点的子节点全部入队。for循环结束就会得到当前层所有节点的累加和,进行除法运算即可。

代码:

public List<Double> averageOfLevels(TreeNode root) {

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.push(root);
        List<Double> resList = new ArrayList<>();

        while (!queue.isEmpty()){

            int curFloorNums = queue.size();
            double sum = 0;
            for (int i = 0; i < curFloorNums; i++) {
                TreeNode curNode = queue.poll();
                sum += curNode.val;
                if (curNode.left != null){
                    queue.add(curNode.left);
                }

                if (curNode.right != null){
                    queue.add(curNode.right);
                }
            }
            resList.add(sum / curFloorNums);
        }
        return resList;
    }

 

题目

  给定一个二叉树,在树的最后一行找到最左边的值。

示例

输入:

    2
   / \
  1   3

输出:
1
输入:

        1
       / \
      2   3
     /   / \
    4   5   6
       /
      7

输出:
7

分析

  此题和上面的思路一样,树的最后一行最左边的值一定是层次遍历时,最后一层第一次访问的节点,那么还采用while循环和for循环的策略,while循环负责遍历树的每一层,for循环负责遍历每一层的每个节点,每开始一个while循环就将当前队列的队首元素赋值给结果变量,最终的结果变量的值一定是最后一行最左边的值。

代码

 public int findBottomLeftValue(TreeNode root) {

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int res = 0;
        while (!queue.isEmpty()){

            int curNums = queue.size();
            res = queue.peek().val;

            for (int i = 0; i < curNums; i++) {
                TreeNode curNode = queue.poll();
                if (curNode.left != null){
                    queue.add(curNode.left);
                }

                if (curNode.right != null){
                    queue.add(curNode.right);
                }
            }
        }
        return res;
    }

解法二:

  按照一般的惯常思路,层次遍历往往都是先将左子节点入队,然后将右子节点入队,根据队列的性质,整个二叉树的节点的访问顺序就是从上到下,从左到右,最后一行的最右边节点,一定是最后一个被遍历到的节点。那么我们就可以利用这个特点来进行一下稍微的改变,那就是每次访问节点的时候,先将右子节点入队,然后再将左子节点入队,那么层次遍历的顺序就变成了从上到下,从右往左,那么最后一行最左边的顶点一定是最后被访问的顶点,那么我们就按照正常的层次遍历访问就行,只需声明一个变量记录每次访问节点,遍历结束的时候,变量值一定是最终的结果。

代码如下:

    public int findBottomLeftValue2(TreeNode root) {
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            root = queue.poll();
            if (root.right != null){
                queue.add(root.right);
            }
            if (root.left != null){
                queue.add(root.left);
            } 
        }
        return root.val;
    }

 

posted @ 2020-08-16 08:53  有心有梦  阅读(185)  评论(0编辑  收藏  举报