程序员老鬼

被裁当天得知自己怀孕了,HR知道后,立马将我从裁员名单中去除,本来都要被裁了,现在却留下来,感谢宝宝。。

刚刷到这个帖子,我第一反应是:

网友说自己本来已经在裁员名单里了,估计心里都开始盘算下一步了。结果当天发现怀孕,HR一知道,立马把她从名单里撤了。你说这事儿,听着像段子,但又特别职场。

Image

公司也不是突然良心发现,多半是怕麻烦。怀孕员工本来就不是想裁就能裁,真硬来,后面一堆劳动纠纷等着。HR反应这么快,说明人家心里也门儿清。

但站在这个女生角度,也挺五味杂陈的。本来是人生大雷,转头因为怀孕“保住工作”。开心吧,好像有点怪;不开心吧,又确实躲过一刀。

面试题:车队

车队这题最容易写错的地方,不是公式,是排序方向。

我一开始看这个题,也下意识想从起点往终点扫,结果越扫越别扭。因为后面的车能不能追上前面的车,判断对象一定是“它前面那辆车”。所以这题别从左往右看,要从离终点最近的车开始往回看。

题目大概是这样:有一批车,目标点是 target,每辆车有当前位置 position[i] 和速度 speed[i]。车不能超过前车,追上之后就会组成一个车队,以前车速度继续走。问最后到达终点时有几个车队。

这题我一般不模拟车怎么跑。真模拟时间、位置,基本就是给自己找麻烦。

只算一件事:每辆车单独跑到终点需要多久。

比如:

time = (target - position) / speed

然后按当前位置从大到小排序,也就是离终点近的车先处理。

前面的车如果到终点需要 5 秒,后面的车需要 3 秒,那后面的车肯定能追上它,最后算一个车队。

但如果后面的车需要 8 秒,它追不上前面的车,就得自己开成一个新车队。

这里有个小坑:不要拿距离比,也不要拿速度比。速度快不一定能追上,位置差得远就不行。最后能不能合并,看的是到达时间。

代码我会这么写,短一点,别绕:

import java.util.Arrays;

classSolution{
publicintcarFleet(int target, int[] position, int[] speed){
int n = position.length;
int[][] cars = newint[n][2];

for (int i = 0; i < n; i++) {
            cars[i][0] = position[i];
            cars[i][1] = speed[i];
        }

        Arrays.sort(cars, (a, b) -> b[0] - a[0]);

int fleet = 0;
double lastTime = -1.0;

for (int[] car : cars) {
double curTime = (target - car[0]) * 1.0 / car[1];

if (curTime > lastTime) {
                fleet++;
                lastTime = curTime;
            }
        }

return fleet;
    }
}

这段代码里,lastTime 不是上一辆车的时间,而是当前最前面那个车队到达终点的时间。

为什么只在 curTime > lastTime 的时候新增车队?

因为当前位置靠后的车,如果它到终点的时间更短,说明它迟早会追上前面的车队。追上以后不能超车,只能并进去,所以车队数量不变。

如果它的时间更长,说明到终点之前追不上,那它只能自己算一个车队。

这题其实就是单调栈的味道,但没必要真写一个栈。因为我们只关心前面车队的最大到达时间,一个变量就够了。

我比较嫌弃这题的一种写法,是先把所有时间算出来,再搞一堆栈 push、pop。能过,但手感不干净。面试里写复杂了,自己还容易解释崩。