Python技术迷

给13k的候选人开25k薪资,结果人家反手要30k,说低于这个数不去。家人们谁懂啊,候选人的薪资底气在哪?

刚看到个贴子,说一家公司给原来拿13k的候选人直接开到25k,结果人家反手要30k,说少一分钱都不去。

Image

帖子底下网友回复挺炸的,有人骂“狮子大开口”,也有人说“说明企业之前压价压习惯了,现在人才开始补回来了”,还有人算账:扣完五险一金、房贷车贷,其实也就那样。

我觉得这事吧,关键是两点:一个是市场价,一个是备胎数。候选人敢开30k,多半是:自己在市场上有对标offer、不急着换、技能确实稀缺,所以底气来自“我有别的选择”。但敢要不代表拿得到,谈崩了也得自己兜着。

从企业角度看,也别只盯着“原来13k”,而是问一句:这个人来,能不能帮我多赚那5k、10k甚至更多?能,那就值得谈;不能,再高也白扯。

算法题:森林中的兔子

题目叫“森林中的兔子”,听着很可爱,对吧,其实是个挺典型的哈希+贪心小题,适合用来练一练脑子和 Python 基本功。

先把题意思说人话: 森林里有一堆兔子,每只兔子被你抓到后,你问它一句:还有多少只兔子跟你颜色一样? 它会回一个整数 y,意思是:除了我以外,还有 y 只跟我一个颜色。那一撮同色兔子总共就是 y + 1 只。

麻烦点在于:你只看到一部分兔子,也不知道它们是不是都老实,有没有同色的还在树林里没出来。现在只知道这一群回答的数字数组 answers,比如 [1, 1, 2],要推断出森林里“最少有多少只兔子”。

直觉想一想。比如来了三只兔子,都说“还有 1 只跟我一样颜色”。那一撮同色的理论大小是 2 只。 如果这三只是同一个颜色,那就矛盾了:一撮只允许 2 只。 那能怎么办?只能拆成两撮颜色: 第一撮:两只说“还有 1 只”,凑满 2 只; 第二撮:单独一只说“还有 1 只”,虽然理论上它说的那撮应该有 2 只,但你没看到另一只,也得算上。 所以这个回答 1 的集合,至少要 4 只兔子在森林里。

大概味道有了,规律就出来了: 所有回答一样的兔子,可以“凑队”,每一队上限是 y+1 只,多出来就得再开一队,同样大小也是 y+1 只,即便没看见这么多,也要按满的算,不然会和“还有 y 只跟我同色”这句话矛盾。

抽象一点: 对每个回答值 y,出现了 count 只兔子。 一队容量是 group_size = y + 1。 需要的队数是向上取整:groups = ceil(count / group_size)。 森林里真实的兔子数,就是 groups * group_size。

实现层面就很简单了:

  1. 用字典统计每个 y 出现了多少次。
  2. 对每个 y 跑一次上面那套公式,累加起来就是答案。
  3. y 为 0 的情况也一样处理,相当于 group_size=1,每只都说“没有别的同色兔子”,那就每只都是独立颜色,一只一组。

用 Python 写一下,大概这样:

from collections import Counter
from typing import List

defnum_rabbits(answers: List[int]) -> int:
"""
    森林中的兔子
    :param answers: 每只兔子回答“还有多少只跟我同色”的数组
    :return: 森林中最少的兔子总数
    """

    counter = Counter(answers)
    total = 0

for y, cnt in counter.items():
        group_size = y + 1# 每一撮同色兔子的理论大小
# 需要多少撮:向上取整 (cnt / group_size)
        groups = (cnt + group_size - 1) // group_size
        total += groups * group_size

return total


if __name__ == "__main__":
# 一些简单测试
    tests = [
        ([1, 1, 2], 5),       # 解释:两个“1” -> 4 只,一只“2” -> 3 只,总共 5?注意看下面…
        ([0, 0, 1, 1, 1], 6),
        ([], 0),
        ([0], 1),
        ([2, 2, 2, 2], 6),
    ]

for answers, _ in tests:
        print(f"answers={answers}, 最少兔子数={num_rabbits(answers)}")

上面第一个例子顺便说清楚,不然后面你会觉得为啥不是 7。 answers = [1, 1, 2]。 回答 1 的有 2 只,group_size = 2,一撮就够,两只都塞进去,总共贡献 2 只兔子。 回答 2 的有 1 只,group_size = 3,只能开一撮,虽然只出现 1 只,但它口径里那撮必须有 3 只,所以贡献 3。 2 + 3 = 5,只是我们没看到的那几只是躲在树林里罢了。

再看一个稍微绕一点的,answers = [1, 1, 1]。 回答 1 的有 3 只,group_size 还是 2。 3 只装不下一撮,向上取整:(3 + 2 - 1) // 2 = 4 // 2 = 2 撮。 一撮 2 只,两撮一共 4 只。虽然只看见 3 只,但为了满足“还有 1 只同色”这句话,只能假设背后还有一只同色的没出来。

这个题有两个常踩坑的点,说一嘴省你踩:

一个是别想着“能多合就多合”,其实上面的分组方式已经是最省兔子的分法了,因为所有回答相同的兔子混在一起随便怎么分,队伍大小都被 y+1 卡死了,多出来的必然要再开一队,而且那队意味着背后要补齐到 y+1 只,不存在再省一点的空间。

另一个是不要按“颜色”思维建模,题目根本没给你颜色,只给了回答 y。如果你强行给每只兔子分颜色 ID,反而会想复杂,比如搞什么回溯、搜索,其实都没必要,按回答分组就是最天然的“颜色桶”。

复杂度也挺友好,统计一遍 O(n),再扫一遍字典 O(k),k 是不同回答的种类数,远小于 n,一般就当 O(n) 用,空间是 O(k)。

这个题写熟了,有个好处是:以后你再遇到那种“若干个元素给了一个限制,按组凑,问最小/最大总量”的题,脑子里会自动浮现出“按值分桶 + 每桶向上取整”的套路,很多看着很吓人的题,其实都能这么拆掉。

行,兔子就说到这,换个题眼睛歇一歇也行。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB