Python技术迷

第一次做外包好像对组长有点喜欢,但听传言说正编外包有阶级区别生殖隔离~

完蛋,这种剧情一看就很职场。第一次做外包,人还没把工位坐热,先对组长有点上头了。关键组长还是正编,这味儿一下就复杂了,工牌都像隔着一层玻璃。

Image

网上老有人说什么“正编外包生殖隔离”,话是损了点,但也不是空穴来风。一个是身份不一样,一个是稳定性不一样,开会坐一桌,心里未必在一个频道。网友也有人劝,喜欢归喜欢,先别脑补太多,很多时候你觉得他照顾你,可能只是组长对接外包的职业素养。还有人更直接:你以为自己在演办公室恋情,HR那边看着像流程事故。

最扎心的不是不能喜欢,是你刚进场,很多边界、很多眼色都还没摸明白。外包这身份本来就容易让人多想,组长今天多问你一句需求卡不卡,晚上就够你回味半天

算法题:墙与门

2147483647 这个数一出来,我一般就不把它当正常业务值看了。 这种题,十有八九不是让你算值,是让你“传播”。 《墙与门》就是这路子:-1 是墙,0 是门,空房间是 INF,要求你把每个空房间改成到最近门的距离。

这题如果你第一眼就想“从每个空房间出发,去找最近的门”,大概率能写出来,但复杂度会比较难看。房间一多,反复搜,CPU 纯打工。

我更信另一种走法:别让房间去找门,让门一起往外扩。

味道有点像线上排查广播类问题。不是 1 万个节点分别去拉配置,而是配置中心一变更,消息一次性往外推。谁先被推到,谁的距离就是最短的。因为 BFS 天生按层扩散,第一波是距离 1,第二波是距离 2,不会乱。

先看核心代码,别整太满:

from collections import deque

defwalls_and_gates(rooms):
ifnot rooms ornot rooms[0]:
return

    m, n = len(rooms), len(rooms[0])
    q = deque()

# 先把所有门塞进队列
for i in range(m):
for j in range(n):
if rooms[i][j] == 0:
                q.append((i, j))

    directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]

while q:
        x, y = q.popleft()

for dx, dy in directions:
            nx, ny = x + dx, y + dy

if nx < 0or nx >= m or ny < 0or ny >= n:
continue
if rooms[nx][ny] != 2147483647:
continue

            rooms[nx][ny] = rooms[x][y] + 1
            q.append((nx, ny))

这里有个点很关键: 我不会单独再搞一个 visited 集合。因为题目本身给了状态位,INF 就代表“还没被更新过”。一旦某个房间被赋值,比如从 2147483647 变成 3,那它其实已经被访问过了,顺手就把判重做掉了。

这个写法干净,内存也省一点。

拿这个例子过一遍就很顺:

rooms = [
    [2147483647, -1, 0, 2147483647],
    [2147483647, 2147483647, 2147483647, -1],
    [2147483647, -1, 2147483647, -1],
    [0, -1, 2147483647, 2147483647]
]

walls_and_gates(rooms)
print(rooms)

输出:

[
    [3, -1, 0, 1],
    [2, 2, 1, -1],
    [1, -1, 2, -1],
    [0, -1, 3, 4]
]

为什么多源 BFS 是正解,不是技巧? 因为所有门同时出发,谁先走到某个空房间,谁就是最近的门。后面别的门再绕过来,只会更远,不可能更短。这一点跟 Dijkstra 那种“不断确认当前最短路”很像,只不过这里每条边权重都一样,所以 BFS 就够了,没必要上优先队列。

还有个常见坑: 有人会写成遇到不是墙就更新。这个不稳。因为题目要的是“最近门距离”,不是“随便写个距离”。你只能更新 INF,不能把已经算好的值再改掉,不然最短路层次会被你搅乱。

这题本身不难,难的是别把简单题写复杂。看到“多个起点、同层扩散、求最近距离”,脑子里最好直接跳出多源 BFS。这个反应一旦形成,岛屿扩散、病毒传播、最近仓库、最短步数,这一串题基本就串起来了。