Python技术迷

谈好了20k,扣了社保2200,公积金1600,个税1400。实际到手,14800。。

这不就是打工人的经典幻觉吗。

面试的时候谈到20k,心里已经开始算了,房租多少,吃饭多少,还能攒点。结果工资条一出来,到手14800,人直接清醒。

社保扣一截,公积金扣一截,个税再来一刀。账面上写着20k,银行卡到账那一刻像被打了个折。最扎心的是,你还不能说它乱扣,很多东西都是正规流程,甚至公积金以后还能用。可问题是,当下吃饭花钱的是你,现在看余额沉默的也是你。

Image

所以网友那句“税后啊”真的太真实了。以后谈薪别光盯着税前,听着确实好听,像人生要起飞。真到发工资那天才发现,起飞的是预期,落地的是到账短信。

HR说20k的时候,打工人眼睛亮了。工资条发下来的时候,眼神又暗回去了。

今日算法题

奖金发少了,员工不服;奖金发多了,老板也不服。

这题卡的不是语法,是规则:每个员工至少拿 1 份奖金;如果某个员工绩效分比左边高,那他奖金必须比左边多;如果比右边高,也必须比右边多。

看着像扫一遍就完事,我第一眼也会想直接从左往右加。但这地方不能只看左边。

比如:

score = [1, 3, 2, 2, 1]

从左往右看,3 比 1 高,奖金加上去没问题。可到了最后一个 1,前面的 2 又必须比它多,这个约束是从右边倒推回来的。只扫一遍,八成漏。

所以我一般不在这种题上玩花活,直接两次扫描,稳。

先给每个人 1 份奖金:

score:  1  3  2  2  1
bonus:  1  1  1  1  1

第一遍从左往右,只处理“比左边绩效高”的情况:

score:  1  3  2  2  1
bonus:  1  2  1  1  1

第二遍从右往左,只处理“比右边绩效高”的情况。这里有个细节,不能直接覆盖,要取 max。因为左边规则可能已经给过奖金了,不能被右边扫描改小。

代码我会这么写:

defmin_bonus(scores):
ifnot scores:
return0

    n = len(scores)
    bonus = [1] * n

for i in range(1, n):
if scores[i] > scores[i - 1]:
            bonus[i] = bonus[i - 1] + 1

for i in range(n - 2, -1, -1):
if scores[i] > scores[i + 1]:
            need = bonus[i + 1] + 1
if need > bonus[i]:
                bonus[i] = need

return sum(bonus)


scores = [1, 3, 2, 2, 1]
print(min_bonus(scores))

这段输出是:

7

对应的奖金分配是:

[1, 2, 1, 2, 1]

这里中间两个 2 分数相同,不需要互相压一头。这个点容易写错,有些人会把“大于等于”也算进去,结果奖金直接多发。

再看一个更明显的:

scores = [5, 4, 3, 2, 1]
print(min_bonus(scores))

如果只从左往右扫,每个人都是 1,肯定不对。倒着扫以后会变成:

[5, 4, 3, 2, 1]

总奖金是 15。

这个题的关键不是“数组遍历”,而是别把局部规则当成全局规则。左边约束管一遍,右边约束再管一遍,最后每个位置拿到两个方向里更严格的那个值。

时间复杂度 O(n),空间复杂度 O(n)。

如果面试官继续追问能不能优化空间,我一般不会马上往下卷。因为这题在业务里更重要的是规则清楚、代码不绕。奖金这种东西,宁可多一个数组,也别写一坨现场没人敢改的逻辑。