刷到个吐槽:朋友跳去大厂,薪资从18k到32k,刚高兴没多久就开始喊累。每天被各种早会、站会、周会、复盘追着跑,真正能安静写代码的时间算下来不到四小时,剩下全在对齐口径、写材料、做PPT。钱是涨了,但节奏和消耗也跟着翻倍。

更扎心的是,他想回头,原公司却不接了。说到底,跳槽不是“涨薪通关”,而是换一套规则重新适应。大厂的体系化有价值,但也意味着沟通成本和过程管理更重;如果你更享受纯开发的成就感,就得提前想清楚自己能不能接受“先对齐再动手”。
给准备跳的人一句:别只盯着数字,问问自己想要的生活和成长是什么;给已经跳的人一句:稳住心态,把能力沉淀下来,路不会只剩一条。
你们知道吧,前两天我在楼下等外卖,手里还拿着电脑,产品那边突然丢个需求说“就那个…单词搜索,你给我讲明白点,最好还能写进公众号里”,我心想这不就是你在一堆格子里找一条“不能走回头路”的路径嘛,跟线上排查链路有点像,trace id 走一遍,走错一步就得撤回重来…哎我这比喻有点土但真挺贴。
单词搜索这题,棋盘是个二维数组,每次从某个格子出发,上下左右走,拼出目标 word。关键坑点就俩:一个是“同一个格子不能重复用”,另一个是“走不通要回退”。所以思路就很自然:DFS + 回溯。你可以理解成我在机房找网线,走到死胡同就得原路退回来,退回来还得把现场恢复成没动过的样子,不然下一次走会被你自己挖的坑绊倒。
实际写起来,我一般不搞额外 visited 矩阵,省点内存,也省点脑子…直接把 board[i][j] 临时改成一个不可能匹配的符号,比如 ‘#’,递归回来再改回去,像不像你排查日志时先加一行 debug,搞定了再删掉,哈哈。
代码我给你们整一个能直接跑的,口味偏工程一点点:先做边界判断,字符不匹配直接剪枝,匹配了就四个方向继续试,任何一个方向成功就直接返回 True。
from typing import Listdefexist(board: List[List[str]], word: str) -> bool:ifnot board ornot board[0] ornot word:returnFalse m, n = len(board), len(board[0])defdfs(x: int, y: int, k: int) -> bool:# k 表示正在匹配 word[k]if board[x][y] != word[k]:returnFalseif k == len(word) - 1:returnTrue ch = board[x][y] board[x][y] = '#'# 标记已用,避免重复走# 四方向试探if x > 0and board[x - 1][y] != '#'and dfs(x - 1, y, k + 1): board[x][y] = chreturnTrueif x + 1 < m and board[x + 1][y] != '#'and dfs(x + 1, y, k + 1): board[x][y] = chreturnTrueif y > 0and board[x][y - 1] != '#'and dfs(x, y - 1, k + 1): board[x][y] = chreturnTrueif y + 1 < n and board[x][y + 1] != '#'and dfs(x, y + 1, k + 1): board[x][y] = chreturnTrue board[x][y] = ch # 回溯恢复现场returnFalse# 从每个起点尝试for i in range(m):for j in range(n):if board[i][j] == word[0] and dfs(i, j, 0):returnTruereturnFalse# 随手测一下if __name__ == "__main__": b = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] print(exist(b, "ABCCED")) # True print(exist(b, "SEE")) # True print(exist(b, "ABCB")) # False复杂度这块也别装神秘:最坏情况就是每个格子都当起点,往外爆搜,近似 O(m*n*4^L)(L 是单词长度),但剪枝很关键:一旦字符不对立刻停。还有个小技巧我平时会顺手加:如果 board 里某个字母数量比 word 里需要的还少,直接 False,别进 DFS 了,省很多时间。