上个月绩效出来,被气到了,都知道我扛了最难的项目,连续三个月没休过周末,结果绩效被打了最低档,那个和领导走得近天天摸鱼的反而是优
刚看到个贴子,说有人拼命干了三个月最难的项目,周末都没休过,结果绩效拿了最低;反倒是天天摸鱼、跟领导关系好的同事成了优。
我觉得这事吧,作为程序员真是太能共鸣了。写代码的世界是二进制,结果职场却是灰色地带。网友们有人说这是“潜规则”,有人劝看开点,但我不太认同。因为现实就是:努力≠价值,领导眼里的“优”往往不只是项目代码跑得好,还包括你能不能让他省心,甚至能不能陪他喝茶聊八卦。换句话说,技术是硬实力,关系却是软实力。
从我的角度看,遇到这种情况不要只闷头写代码,还得学会写“可见度”。就像程序里的日志,如果没人看到你的贡献,等于白跑一遍逻辑。同时也别太纠结眼前的委屈,把积累当版本更新,迟早会遇到懂你价值的团队。【备注:文末可领最新资料】
算法题:可能的二分法
先把问题说人话:有 n 个人,给你一堆“互相讨厌”的配对 (a, b)。问能不能把人分成两组,保证每一对讨厌的俩人不在同一组。直觉上这不就是“把矛盾分到两边”嘛。计算机里的标准模型叫图的二分图判定:把人当点,讨厌关系当边,能否把图染成两种颜色,使得每条边两端颜色不同。
思路怎么落地
图是可能不连通的,所以要从 1..n 都扫一遍;遇到还没决定去哪个组的人,就随便给个组(比如颜色 0),然后向外扩散:他的每个邻居都得是另一种颜色(1)。如果扩散时发现有个邻居早就被染成了同色,那就凉了,说明矛盾无法被隔离。
这其实是“染色法”(DFS/BFS 都行)。时间复杂度就是把点和边各看一遍:O(n + m),m 是讨厌对的数量。空间是邻接表和颜色数组:O(n + m)。
代码(Java,DFS 版本)
import java.util.*;
publicclassSolution{
publicbooleanpossibleBipartition(int n, int[][] dislikes){
// 建图:1..n,用 n+1 长度省心
List<List<Integer>> g = new ArrayList<>(n + 1);
for (int i = 0; i <= n; i++) g.add(new ArrayList<>());
for (int[] e : dislikes) {
int a = e[0], b = e[1];
g.get(a).add(b);
g.get(b).add(a);
}
// -1 未染色,0/1 两种颜色(两组)
int[] color = newint[n + 1];
Arrays.fill(color, -1);
for (int i = 1; i <= n; i++) {
if (color[i] != -1) continue;
if (!dfs(i, 0, color, g)) returnfalse;
}
returntrue;
}
privatebooleandfs(int u, int c, int[] color, List<List<Integer>> g){
color[u] = c;
for (int v : g.get(u)) {
if (color[v] == -1) {
if (!dfs(v, c ^ 1, color, g)) returnfalse;
} elseif (color[v] == c) {
returnfalse; // 碰到同色冲突
}
}
returntrue;
}
}
常见坑位
有几个小细节别踩: (1)不连通:一定要从每个未访问的点开一个新 DFS/BFS。 (2)数组开到 n+1:题里人从 1 编号,别少开一位。 (3)递归深度:极端链状图时 DFS 会很深,担心栈的话就用 BFS 染色,逻辑一模一样。
并查集也能做
把“讨厌”理解成“必须在对立集合”,可以用并查集把同一人的所有“敌人的敌人”并在一起,如果发现某人和他的敌人被并进同一集合,直接返回失败。实现略长,但思路也很清晰,适合习惯并查集的同学。
这题的核心就是“二分图判定=图染色”。建邻接表,颜色数组从未染到两色,连通块逐个跑,遇到同色冲突说明不行;一路通畅就行。写熟这个模版,其他“喜欢/讨厌、奇偶约束、两阵营对立”的题,也能顺手拿下。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html