二叉树的层平均值、 找树左下角的值(力扣第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; }