某大厂hr吐槽:裁完11位员工后,自己也被优化了~
刚刷到这个吐槽,给我看得有点想笑,又笑不太出来。去年她还是裁员那个,老板一句“月底前清掉HC”,她就挨个去谈,11个人,一个都没落下。
结果风水转得是真快,今年3月,轮到她自己被优化了。
你说她冤吧,也很难说。毕竟去年那11个人坐对面的时候,她大概率也是一脸职业微笑,嘴上讲理解,手里继续递解除协议。可你说她活该吧,好像也不全是,很多HR说到底也就是拧螺丝的,老板让砍谁就砍谁。
最扎心的还是这个,昨天你还是规则执行者,今天规则就落你头上了,连台词都不用改,真挺讽刺的。
算法题:数字的补数
一个数写成二进制,最烦的不是长,而是前面那一串没意义的 0。 “数字的补数” 这题,本质上就干一件事:只把有效位翻转,别把前导 0 也算进去。这个地方很多人第一眼就会写错,直接 ~num 一把梭,结果答案基本都不对。因为 Python 里的整数不是你想的那种固定 8 位、16 位,它是带符号扩展的,~5 得到的是 -6,这玩意一看就知道不对劲。整体写法我按更偏实战的方式来组织,风格上贴近你给的参考气质,但不复用原文表达。
先拿题目里最常见的例子说,5 的二进制是 101。 补数不是把它补成 000...010 那种全长翻,而是只翻这 3 位,得到 010,也就是 2。
所以关键不是翻转本身,关键是先造出一张“只覆盖有效位”的掩码。
deffind_complement(num: int) -> int:
mask = 1
while mask <= num:
mask <<= 1
return (mask - 1) ^ num
这个写法我比较喜欢,原因很直接。mask 最后会停在比 num 最高位再高一位的位置。比如 num = 5,二进制 101:
mask = 1# 001
mask = 2# 010
mask = 4# 100
mask = 8# 1000
这时候 mask - 1 就是 111,刚好把有效位全覆盖。 后面再异或:
111 ^ 101 = 010
答案就是 2。
有些人喜欢转字符串做,也能过,但我一般不太信这种写法。题目明明考二进制和位运算,你上来 bin()、切片、再转回整数,能做是能做,味道不对。而且面试里这么写,面试官大概率会继续追问你位运算版本。
再给一个更顺一点的版本,不用循环找掩码长度,直接用 bit_length():
deffind_complement(num: int) -> int:
bits = num.bit_length()
mask = (1 << bits) - 1
return mask ^ num
这版更短。 比如 num = 10,二进制是 1010,长度 4,那么:
mask = (1 << 4) - 1# 1111
1111 ^ 1010# 0101
结果就是 5。
最后说下边界。 如果题目允许 num = 0,那要单独处理一下,因为 0.bit_length() 是 0,掩码会变成 0,翻不出你想要的结果。
deffind_complement(num: int) -> int:
if num == 0:
return1
mask = (1 << num.bit_length()) - 1
return mask ^ num
这题不难,坑也就一个:别拿 ~num 直接交卷。 看到“补数”两个字,先别急着翻,先确认你到底翻的是哪几位。这个顺序错了,后面代码写再快也白搭。