某大厂员工爆料:我们技术总监,40岁,是行业里公认的大牛。他立了个规矩:周3定为不加雷打不动,号召大家下班去生活
这技术总监有点东西啊。
40岁,行业里公认的大牛,按理说这种人最容易把“拼命干”挂嘴边,结果人家反手定了个规矩:周三不加班,雷打不动。
技术大牛说这个,底下人真敢信。要是换个只会喊口号的管理层,说“大家早点走”,员工估计电脑都不敢关,生怕第二天被问进度。
很多公司最烦的不是忙,是那种没意义的耗。白天会开一堆,晚上再假装进入状态,最后人累得要死,活也没见快多少。
这位总监讨厌的,估计就是这种班日味儿。周三硬切一刀,提醒大家别把生活全交给公司。挺难得的,HR看完估计都沉默了。
算法题:最优除法
1000 / 100 / 10 / 2 这题,别急着上动态规划。
我第一次看“最优除法”,下意识也想枚举括号。因为只要是括号问题,脑子里很容易跳出区间 DP。
但这题有点阴。它不是让你算所有可能值,而是让你返回一个能让结果最大的表达式。
比如:
nums = [1000, 100, 10, 2]
不加括号默认是:
1000 / 100 / 10 / 2 = 0.5
但如果写成:
1000 / (100 / 10 / 2)
里面先算:
100 / 10 / 2 = 5
最后就是:
1000 / 5 = 200
差距一下就出来了。
这地方我一般不会先写代码,而是先盯住第一个数。
整个表达式长这样:
a0 / a1 / a2 / a3 ...
无论怎么加括号,a0 一定在最前面。要让整体最大,本质就是让 a0 后面的那个“分母”尽量小。
那怎么让分母小?
从 a1 开始,最小的写法就是:
a1 / a2 / a3 / ... / an
因为后面的数全部拿来除它。于是整体最优就是:
a0 / (a1 / a2 / a3 / ... / an)
注意这里有个小坑:括号只需要一层,不要写成:
a0 / ((a1 / a2) / a3)
虽然数学结果一样,但题目通常要求表达式不要有多余括号。
代码不用搞复杂,我会这么写:
classSolution{
public String optimalDivision(int[] nums){
int n = nums.length;
if (n == 1) {
return String.valueOf(nums[0]);
}
if (n == 2) {
return nums[0] + "/" + nums[1];
}
StringBuilder expr = new StringBuilder();
expr.append(nums[0]).append("/(");
for (int i = 1; i < n; i++) {
if (i > 1) {
expr.append("/");
}
expr.append(nums[i]);
}
expr.append(")");
return expr.toString();
}
}
这段代码里只分三种情况。
一个数,直接返回。
两个数,不能加括号,写成:
a/b
三个及以上,才需要把后面整段包起来。
比如:
[2, 3, 4]
输出:
2/(3/4)
如果写成:
(2/3)/4
结果明显小了。
这题真正容易写偏的地方,不是代码,而是把它想重了。区间 DP 当然能做,但最后会发现你费劲算了一圈,答案结构永远长一个样。
我更喜欢这种题的原因也在这。
它看起来像算法题,最后考的其实是你有没有先把表达式拆开看。代码只有十几行,思路错了,写一屏也白搭。