Python技术迷

和领导大吵一架,第二天就被裁了。两周后拿了月薪 1.5w的 offer,没想到HR却发消息说:有人跟我说了你的情况,你不用来了

跟领导当场拍桌子,第二天喜提裁员,这剧情放职场里都不算新鲜了。真惨的是后半段:人家缓了两周,好不容易拿到个1.5w的offer,HR又来一句“有人跟我说了你的情况,你不用来了”。

Image

评论区有人说,吵归吵,领导背后递话就太脏了。也有人说,职场别信什么体面分手,很多人笑着送你走,转头就给你埋雷。我看这事最恶心的,不是裁员,是那种“我还得让你找不着下家”的阴劲儿。明面上讲规则,背地里搞口碑封杀,HR看完消息估计都懒得装客气。

所以现在找工作,真别觉得离职就结束了。有些领导你以为只是脾气差,实际上是心眼小还记仇。吵赢那一刻挺爽,后劲上来,才知道谁在掐你脖子。

算法题:自除数

这题看着像遍历,真写起来,最容易把自己绕进去的不是循环,是“自除”这两个字到底怎么算。

比如 128。 1 能整除,2 能整除,8 也能整除,所以它是自除数。

但 120 就不行。不是因为大,而是因为里面有个 0。你一旦真去做 120 % 0,程序就直接给你脸色看了。这种题我第一眼一般先盯这种边界:有没有 0,数字是不是要保留原值,拆位的时候会不会把原数拆没了。

题目本身不复杂,给一个区间,找出里面所有自除数。做法也不花哨:每个数过一遍,把它按位拆开检查。每拆出一位,就判断两件事:

第一,这一位不能是 0。 第二,原数必须能被这一位整除。

只要有一位不满足,这个数就可以直接踢掉,不用再往下看了。

Python 写这种题挺顺手,代码不用绕:

defis_self_dividing(num: int) -> bool:
    x = num
while x > 0:
        digit = x % 10
if digit == 0or num % digit != 0:
returnFalse
        x //= 10
returnTrue


defself_dividing_numbers(left: int, right: int) -> list[int]:
    ans = []
for num in range(left, right + 1):
if is_self_dividing(num):
            ans.append(num)
return ans


print(self_dividing_numbers(1, 22))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]

这段代码里有个小地方别写丢了:x = num。 因为你后面要不停地 x //= 10 拆位,如果直接拿 num 去拆,最后原值没了,后面做整除判断就不对了。这种错很常见,尤其是手快的时候。

再拿几个数过一下就很清楚了。

print(is_self_dividing(128))  # True
print(is_self_dividing(120))  # False
print(is_self_dividing(26))   # False

26 不行,因为 26 不能被 6 整除。120 不行,因为出现了 0。128 则一路通过。

这题的时间复杂度其实也很老实。区间里每个数都检查一次,每次检查的成本就是这个数的位数,所以大致可以看成 O(n * k),n 是区间长度,k 是位数。范围不大的时候,这种写法够用了,没必要想太多奇技淫巧。

这种题放在算法题里算不上难,但挺适合练基本功。尤其是这种“按位拆数字”的写法,后面碰到回文数、各位和、快乐数这类题,基本还是这套手法。别嫌简单,简单题最容易把细节写丢。0 不先拦,原值不备份,代码都跑不稳。