程序员老鬼

某程序员爆料:没买房被组长针对了,他自己的房估计亏了五百万,现在对我总阴阳怪气,说我不买房干嘛,还说我的存款就算。。

刚看到个贴子,说有程序员吐槽自己没买房被组长疯狂针对。组长房子自己亏了五百万,现在见谁都要劝一句“你咋还不买房”“背星毕业都不怕”。这画风是真熟悉。

Image

我觉得这事吧,问题根本不在房子,而在情绪迁怒。亏钱是他的事,可他把气撒到同事身上,这就有点离谱了。

从职场的角度看,一个人成熟不成熟,看他能不能把情绪和工作分开。你房子套牢了,那是投资判断;你阴阳同事,那就是职业素养问题。再说了,别人买不买房、存了多少钱,跟你绩效一毛钱关系都没有。

不过话说回来,这种情况下别硬刚,保持边界就行。

他阴阳你,你就当背景噪音,专心干自己的活。说到底,职场不是比谁嘴碎,而是比谁更能提供价值。

面试题:二叉树的层平均值

先说结论:这道「二叉树的层平均值」本质就是一层一层地遍历二叉树,把每一层所有节点的值加起来,再除以这一层的节点个数,最后按层顺序返回一个平均值列表就好了。

题目大意是这样的:

给你一棵二叉树,树里每个节点有一个整数值。 你要返回一个数组 / 列表,第 i 个元素是第 i 层所有节点值的平均数。

举个小例子,假设树长这样:

    3
   / \
  9  20
    /  \
   15   7

那各层是:

  • 第 0 层: [3],平均值 3.0
  • 第 1 层: [9, 20],平均值 (9 + 20) / 2 = 14.5
  • 第 2 层: [15, 7],平均值 (15 + 7) / 2 = 11.0

结果就是 [3.0, 14.5, 11.0]。

自然想到的解法:层序遍历 + 统计

只要你做过「二叉树的层序遍历」(也就是 BFS,从上往下一层层扫),这题基本就已经解决一半了。

核心思路:

  1. 用一个队列 Queue<TreeNode>,先把根节点 root 丢进去。

  2. 每次从队列里「拿出当前这一层」所有节点:

  • 如果它有左孩子,就把左孩子入队;
  • 如果它有右孩子,就把右孩子入队。
  • 先记下当前队列的大小 size,这就是这一层有多少个节点。

  • 循环 size 次: 每次弹出一个节点,把它的值加到当层的 sum 里。

  • 这一层处理完之后,用 sum / size 算出平均值,丢进结果列表。

  • 队列清空,说明树遍历完了。

  • 注意两个细节:

    • 平均值要用 double 来存,不要用整型(不然会被整除)。
    • sum 的类型用 double 或 long 都可以,我习惯用 double,少一步强转。

    先来个常规的 TreeNode 定义:

    publicclassTreeNode{
    int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {}
        TreeNode(int val) {
    this.val = val;
        }
        TreeNode(int val, TreeNode left, TreeNode right) {
    this.val = val;
    this.left = left;
    this.right = right;
        }
    }

    然后是主方法:

    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Queue;

    publicclassSolution{
    public List<Double> averageOfLevels(TreeNode root){
            List<Double> res = new ArrayList<>();
    if (root == null) {
    return res;
            }

            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);

    while (!queue.isEmpty()) {
    int size = queue.size();      // 当前层节点数
    double sum = 0.0;             // 当前层节点值之和

    for (int i = 0; i < size; i++) {
                    TreeNode node = queue.poll();
                    sum += node.val;

    if (node.left != null) {
                        queue.offer(node.left);
                    }
    if (node.right != null) {
                        queue.offer(node.right);
                    }
                }

                res.add(sum / size);
            }

    return res;
        }
    }

    这段逻辑对应上面的思路非常直接:

    • while (!queue.isEmpty()):一层一层往下走;
    • int size = queue.size():当前层有多少个节点,就循环多少次;
    • 每层结束后 res.add(sum / size):记录这一层的平均值。

    再说一个 DFS 解法(顺便拓宽一下思路)

    虽然 BFS 写起来最顺手,不过也可以用 DFS 做: 思路是「前序遍历」整棵树,同时维护两个数组 / 列表:

    • levelSum[level]:第 level 层所有节点值的和
    • levelCount[level]:第 level 层节点数量

    遍历的时候,把当前节点的值加到对应层的 sum 上,同时 count + 1。 遍历结束后,再逐层用 sum / count 算平均值。

    Java 写起来像这样:

    import java.util.ArrayList;
    import java.util.List;

    publicclassSolutionDFS{

    private List<Double> levelSum = new ArrayList<>();
    private List<Integer> levelCount = new ArrayList<>();

    public List<Double> averageOfLevels(TreeNode root){
            dfs(root, 0);

            List<Double> res = new ArrayList<>();
    for (int i = 0; i < levelSum.size(); i++) {
                res.add(levelSum.get(i) / levelCount.get(i));
            }
    return res;
        }

    privatevoiddfs(TreeNode node, int level){
    if (node == null) {
    return;
            }

    // 还没有这个层级,先初始化
    if (level == levelSum.size()) {
                levelSum.add(0.0);
                levelCount.add(0);
            }

    // 更新这一层的 sum 和 count
            levelSum.set(level, levelSum.get(level) + node.val);
            levelCount.set(level, levelCount.get(level) + 1);

            dfs(node.left, level + 1);
            dfs(node.right, level + 1);
        }
    }

    这个方式比 BFS 稍微绕一点,但是能帮你熟悉「递归里带着层级信息」这种套路,很多树相关题目都会用到。

    复杂度简单算一下

    不管是 BFS 还是 DFS:

    • 每个节点只会访问一次,所以时间复杂度都是 **O(n)**,n 是节点总数。

    • 额外空间:

      • BFS:队列最坏情况下会装下某一层全部节点,空间复杂度是 **O(width)**,width 是树的最大宽度。
      • DFS:递归深度最多是树的高度,空间复杂度是 **O(height)**,另外还要存每一层的 sum 和 count。

    整体来说,这题属于那种「会层序遍历就能做」的题,非常适合用来熟悉二叉树 BFS 的模板写法。你可以先把 BFS 版本默写几遍,确保自己在任何时候都能写出来,再顺手把 DFS 版本也敲一遍,当作加餐训练。

    -END-

    我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

    最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链接我微信:hls404