同事被炒鱿鱼了,结果人家动作快得跟闪电似的,东西一会儿就收拾走了,工作群退,联系人一删,干净利落。。
这位同事执行力也太强了。
前脚被通知走人,后脚就开始清场,桌面一收,电脑一交,杯子、充电器、小摆件全带走,速度快得像早就演练过。工作群退得也干脆,通讯录该删删,该拉黑拉黑,一点多余情绪都不留。
最搞的是中午领导还想找他问事,估计是想补两句流程,或者让人家交代点什么,结果一看,好家伙,自己也没了。消息发不出去,人也联系不上,领导这会儿脸估计都僵住了。
其实这事挺打工人的。公司裁人的时候讲效率,员工离开的时候也讲效率,大家都别演深情。你都把人清出去了,还指望人家继续待命、随叫随到,那不就是想多了嘛。
有些题一看就想两层循环:每个角色去找有没有人攻击、防御都比它高。
这个写法我第一眼就不太信。
角色数量一上来,O(n^2) 基本就是等着超时。这个题真正别扭的地方不在“比较两个属性”,而在怎么避免同攻击力的角色互相误伤。
题目说,一个角色是弱角色,必须存在另一个角色:
攻击力更高,防御力也更高。
注意,是攻击力更高,不是大于等于。
比如:
[5, 5]
[5, 9]
第二个防御高,但攻击一样,不能说明第一个弱。
这个坑不处理,答案就会偏大。
我的写法一般是先排序:
攻击力从大到小排。
攻击力一样时,防御力从小到大排。
然后从前往后扫,维护一个 maxDefense,表示前面已经见过的最大防御。
因为攻击力是降序,所以前面那些角色攻击力一定不小于当前角色。又因为同攻击力内部按防御升序排,同攻击力的前面防御只会更小,不会把当前角色误判成弱角色。
代码直接看:
import java.util.Arrays;
classSolution{
publicintnumberOfWeakCharacters(int[][] properties){
Arrays.sort(properties, (a, b) -> {
if (a[0] != b[0]) {
return b[0] - a[0]; // 攻击力高的排前面
}
return a[1] - b[1]; // 攻击力一样,防御低的排前面
});
int weak = 0;
int maxDefense = 0;
for (int[] role : properties) {
int defense = role[1];
if (defense < maxDefense) {
weak++;
} else {
maxDefense = defense;
}
}
return weak;
}
}
这里最关键的是同攻击力的排序方向。
如果你写成攻击力降序、防御力也降序,就会出问题。
比如:
[7, 10]
[7, 3]
扫到 [7, 3] 时,前面已经有个 maxDefense = 10,代码会觉得它是弱角色。
但实际上它不是。
因为攻击力一样,不能算被压制。
所以同攻击力必须让防御小的先出现,这样同组里不会出现“前面防御比当前大”的情况。maxDefense 真正能压住当前角色的,只能来自攻击力更高的那一批。
这题还有一种写法是攻击力升序,然后倒着扫,也能做。但我不太喜欢,边界更绕一点。降序往前扫,人的脑子比较顺:前面都是更强攻击力的候选人,只要防御也压过来,当前就是弱角色。
复杂度也干净。
排序是 O(n log n),后面扫描一次是 O(n),额外空间除了排序本身,基本就是常数。
这题看着像数组题,实际考的是排序规则。两个字段一起排,最怕的就是把“同攻击力”这批数据处理错。攻击力相同的时候,不管防御差多少,都不能互相判弱。抓住这一点,代码就没什么花活了。