程序员老鬼

前鹅厂员工:前leader真不当人啊,之前和他有些不愉快,拿低绩效走人,为了背调送了一瓶茅台和三千多的冬虫草礼盒,结果。。

刚看到个前鹅厂员工的贴子,说自己离职时因为怕背调被卡,还特地送了茅台和冬虫草礼盒,结果前leader不但收了,还在背调里踩了一脚,害他丢了百万offer 。

Image

我觉得这事吧,真挺让人寒心的。送礼这套在职场早就不保险了,本质上你把主动权交给别人手里,人家收了东西照样可以翻脸不认。网友们有说“活该不该送”的,也有人骂leader缺德,但换个角度想,问题的根本还是在于职场规则就是信息差和权力差。

从我的角度看,比起花钱求心安,不如尽量把可控的部分做到最好,比如离职时保持职业体面,少留口实。毕竟声誉才是最硬的背调通行证。领导不当人你没法控制,但能控制的是别让自己被反噬。【备注:文末可领最新资料】

算法题:相同颜色的最大子树

“相同颜色的最大子树”我这里按严格子树理解:选树上某个点做根,它的整棵子树(它和所有后代)里每个点颜色都一样;在所有满足条件的子树里,找结点数最大的那棵。如果没有更大,至少每个单独结点本身算大小为 1 的同色子树。

这个就适合后序 DFS。到某个结点 u:

  1. 先把所有孩子子树都算完,拿到它们是否“同色子树”的判定和各自大小;
  2. 只有当每个孩子子树本身同色且孩子根颜色与 u 的颜色一致时,u 的整棵子树才是同色的,大小就是 1 + sum(孩子大小);
  3. 否则,u 这棵就不是同色子树,但答案仍可能来自某个孩子,于是继续向上返回“不同色”的标记。

用一个全局 ans 维护最大值。为了防止走回头路,用 parent 或者在 DFS 时带上 fa。

import java.util.*;
publicclassSameColorMaxSubtree{
static List<Integer>[] g;
staticint[] color;           // 节点颜色
staticint n, ans;

staticclassRet{
boolean mono; // 以该点为根的整棵子树是否同色
int size;     // 若mono=true则为子树大小;否则size无所谓
        Ret(boolean m, int s){ mono = m; size = s; }
    }

static Ret dfs(int u, int fa){
boolean ok = true;  // 先假设能成为同色子树
int sum = 1;        // 先算上自己
for (int v : g[u]) {
if (v == fa) continue;
            Ret r = dfs(v, u);
// 只要有孩子不是同色子树,或者孩子颜色与我不同,就宣告失败
if (!r.mono || color[v] != color[u]) ok = false;
if (r.mono) sum += r.size; // 只有孩子是同色子树才可并入
        }
if (ok) {
            ans = Math.max(ans, sum);
returnnew Ret(true, sum);
        } else {
// 自己这棵不行,但单节点永远是一棵同色子树,更新一下答案
            ans = Math.max(ans, 1);
returnnew Ret(false, 0);
        }
    }

// 演示:输入 n、颜色数组、边列表
publicstaticintsolve(int n_, int[] color1Indexed, int[][] edges){
        n = n_;
        color = color1Indexed;
        g = new ArrayList[n + 1];
for (int i = 1; i <= n; i++) g[i] = new ArrayList<>();
for (int[] e : edges) { // 无向树
int a = e[0], b = e[1];
            g[a].add(b); g[b].add(a);
        }
        ans = 1;
        dfs(1, 0); // 任意点作根皆可,这里用1
return ans;
    }

// 小样例
publicstaticvoidmain(String[] args){
int n = 7;
int[] col = newint[]{0, 1,1,1, 2,2,2, 1}; // 1..7 用,0位占位
int[][] edges = {
            {1,2},{1,3},{1,4},{3,5},{3,6},{6,7}
        };
        System.out.println(solve(n, col, edges)); // 输出同色最大子树大小
    }
}

复杂度和易错点

  • 时间复杂度:每条边走一次,O(n);额外空间为递归栈 O(n)。

  • 易错点:

    • 别把“同色最大连通块”误当题意(那个是 DFS/并查集按相同颜色扩展,定义不同,下文补充)。
    • 只有当所有孩子子树都同色且颜色等于当前点时,才能把孩子规模“并入”;否则当前点这棵就失败,但别忘了单节点也能更新答案为 1。
    • 输入是树(无环),记得在 DFS 里用 fa 防回边。

如果题目是“相同颜色的最大连通块”(不要求整棵子树、只要相同颜色相连即可),那就按颜色分组,图上对每个未访问点做一遍只走“同色边”的 DFS/BFS,统计块大小,取最大;复杂度同样 O(n)。

-END-

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

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