年薪60万华为小领导爆料:在华为是个小领导,带20个外包,天天催他们干活,甚至通宵改 BUG,自己啥都没干,一直摘果子。。
刚看到个贴子,说有个华为年薪60万的小领导吐槽:自己带着二十个外包天天催活、催通宵改BUG,结果自己几乎啥都没干,全在摘果子,心里过意不去。
从我的角度看,领导本来就不是干活最多的那个人,他的价值在于把活推进去、把资源协调好、把团队顶住压力。就像打游戏,你是队长,不一定输出最高,但你得指挥、得扛锅。网友说他“摘果子”,但职场本来就是按角色分工来分收益的,不是按谁敲键盘次数来算。
不过话说回来,如果他真觉得良心不安,那多为团队争点资源、多让大家少熬几个通宵,这才比较实际。光自责没用,还容易显矫情。
职场里谁的活都不轻松,各司其职、把团队带好,比“我是不是干得最多”重要多了。【备注:文末可领最新资料】
面试题:除法求值
下面就聊聊这道很典型、但又挺适合讲故事的题——「除法求值」(Evaluate Division),顺便用 Java 写一版好理解的解法。
大概意思是这样:
给你一堆“等式”和它们的结果,比如:
a / b = 2.0b / c = 3.0
然后又给你很多问句:
a / c = ?c / a = ?x / y = ?…
如果能通过前面的等式推出来,就算出结果;推不出来,就返回 -1.0。
上面这个例子里:
a / c = (a / b) * (b / c) = 2.0 * 3.0 = 6.0c / a = 1 / (a / c) = 1 / 6.0如果出现从来没见过的变量,比如 a / x,肯定是-1.0。
用人脑看很简单,但要写代码就得想个统一的模型。
把等式看成一张“带权图”
最自然的想法: 每个变量(a、b、c…)当成图里的一个“点”,每个等式当成一条“有方向、有权重”的边。
比如有 a / b = 2.0,我们就建两条边:
a -> b权重2.0b -> a权重1 / 2.0
再有 b / c = 3.0,就多两条边:
b -> c权重3.0c -> b权重1 / 3.0
这样如果要算 a / c,其实就是在图里找一条从 a 到 c 的路径:
a -> b->c
沿途把权重乘起来:2.0 * 3.0 = 6.0。
所以问题就变成了:
在一张带权有向图里,求“起点到终点”的路径乘积,如果走不到,就返回 -1。
图有了,那怎么找路径?DFS / BFS 都行,这里用 DFS 讲起来比较顺。
用 DFS 解“除法求值”
大致步骤:
建图用
Map<String, Map<String, Double>> graph存边。
graph.get("a").get("b") = 2.0表示a -> b权重为2.0。
处理查询对每个查询 x / y:
如果 x或y根本不在图里,直接返回-1.0。如果 x.equals(y),且这个点存在,返回1.0。否则,从 x开始 DFS 找到y,一路乘积累积结果。
DFS 细节写个递归函数 dfs(cur, target, acc, visited):
逻辑是:
没访问过就继续 DFS: dfs(next, target, acc * weight(cur->next), visited)谁先找到就返回谁;都找不到就返回 -1.0。
如果
cur就是target,返回acc。否则遍历
cur的所有邻居next:
cur:当前节点target:目标节点acc:从起点到当前节点的乘积visited:防止死循环(比如 a->b, b->a 这种环)
下面这段代码就是完整写法,尽量写得直白一点:
import java.util.*;
publicclassEvaluateDivision{
publicdouble[] calcEquation(List<List<String>> equations, double[] values,
List<List<String>> queries) {
// 1. 建图:a / b = k => a->b:k, b->a:1/k
Map<String, Map<String, Double>> graph = new HashMap<>();
for (int i = 0; i < equations.size(); i++) {
List<String> eq = equations.get(i);
String a = eq.get(0);
String b = eq.get(1);
double k = values[i];
graph.putIfAbsent(a, new HashMap<>());
graph.putIfAbsent(b, new HashMap<>());
graph.get(a).put(b, k);
graph.get(b).put(a, 1.0 / k);
}
double[] ans = newdouble[queries.size()];
// 2. 处理每一个查询
for (int i = 0; i < queries.size(); i++) {
List<String> q = queries.get(i);
String x = q.get(0);
String y = q.get(1);
if (!graph.containsKey(x) || !graph.containsKey(y)) {
// 没见过的变量,肯定算不出来
ans[i] = -1.0;
} elseif (x.equals(y)) {
// 自己除自己 = 1
ans[i] = 1.0;
} else {
Set<String> visited = new HashSet<>();
ans[i] = dfs(graph, x, y, 1.0, visited);
}
}
return ans;
}
// 从 cur 出发,到 target,当前乘积是 acc
privatedoubledfs(Map<String, Map<String, Double>> graph,
String cur, String target,
double acc, Set<String> visited){
if (cur.equals(target)) {
return acc;
}
visited.add(cur);
Map<String, Double> neighbors = graph.get(cur);
for (Map.Entry<String, Double> entry : neighbors.entrySet()) {
String next = entry.getKey();
double weight = entry.getValue();
if (visited.contains(next)) {
continue;
}
double res = dfs(graph, next, target, acc * weight, visited);
if (res != -1.0) {
// 找到了就一路返回
return res;
}
}
// 这条路走不通
return -1.0;
}
// 简单测一下
publicstaticvoidmain(String[] args){
EvaluateDivision solver = new EvaluateDivision();
List<List<String>> equations = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("b", "c")
);
double[] values = {2.0, 3.0};
List<List<String>> queries = Arrays.asList(
Arrays.asList("a", "c"),
Arrays.asList("c", "a"),
Arrays.asList("a", "e"),
Arrays.asList("a", "a")
);
double[] res = solver.calcEquation(equations, values, queries);
System.out.println(Arrays.toString(res));
// 输出大致是:[6.0, 0.166..., -1.0, 1.0]
}
}
简单回顾下整个流程(不搞那种特别抽象的总结):
把“除法关系”变成一张图,边上放比例。
查询的时候就是:在图里找一条路,从起点走到终点,一路把边的权值乘起来。
走不到就
-1.0。DFS 写起来不复杂,注意:
变量可能不存在; 图可能有环,记得 visited;自除情况返回 1.0。
这题思路一旦和“带权图 + 路径乘积”对上号,后面基本就是体力活了。你可以再试着把 DFS 换成 BFS,或者用并查集带权重写一版,对图论和并查集的理解都会更清晰。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html