女朋友嫌弃我是外包,说我给不了她安全感,养不起一个家,比不上她前男友,要和我分手。。。
这年头,干外包的确实不太吃香,工资不高、加班多、待遇也不稳定,连谈个恋爱都能被看不起,兄弟,我太懂你了。我以前也是干外包的,那时候一个月拿五六千,房租一交完,连吃顿火锅都得犹豫半天。谈恋爱嘛,确实难撑场面。
但话说回来,如果一个人真的在乎你,哪怕你暂时没什么钱,她也会愿意陪你吃苦一起熬,而不是用工资来衡量感情。
她现在说要走,说白了就是不想再赌下去了。你舍不得,这很正常,但生活总得继续,你得对得起自己,别为了一个不愿陪你走下去的人把自己搞垮。
我觉得,先别急着去改变自己迎合别人,搞清楚你自己想成为什么样的人,再慢慢去努力。干我们这行的,只要脑子还清醒,愿意学,就总有机会。别怕失去谁,怕的是你把自己搞丢了。
算法题:单词拆分
刷算法题刷多了,有些题你一眼就能看出是动态规划,这题“单词拆分”(Word Break)就是这种典型的题型之一。题目大概意思是给你一个字符串 s,再给你一个字符串字典 wordDict,你要判断能不能把 s 拆成字典里有的那些单词拼起来。
一开始我看这题觉得有点像暴力搜索,枚举每个可能的切割点,看剩下的子串在不在字典里,理论上是能做,但复杂度高得离谱,直接超时。后来回过头想想,这是明显的子问题重叠 + 最优子结构,于是动态规划安排上。
解决这题的思路是构造一个布尔数组 dp,长度为 len(s)+1,dp[i] 表示前 i 个字符是否可以被字典拼接出来。dp[0] 初始为 True,表示空字符串可以被成功拆分。然后我们从前往后迭代,枚举每个位置 i,再从头到 i 枚举每个可能的切割点 j,只要 dp[j] 为 True 且 s[j:i] 在字典中,就可以断定 dp[i] = True。最后返回 dp[len(s)]。
用 Python 写一下,大概长这样:
defwordBreak(s, wordDict):
word_set = set(wordDict)
dp = [False] * (len(s) + 1)
dp[0] = True
for i in range(1, len(s) + 1):
for j in range(i):
if dp[j] and s[j:i] in word_set:
dp[i] = True
break
return dp[-1]
为什么要用 set 而不用 list?因为查找 s[j:i] in wordDict 的效率,set 查找是 O(1),list 是 O(n),用 list 跑大的用例绝对超时。
其实刚入行那会儿,我就被这种题虐得死去活来,因为没掌握动态规划的本质,总是死背模板。后来理解了,其实关键就是“前面的子问题结果能不能帮我推导出当前的结果”,只要是这种模式,就值得往动态规划的方向去考虑。
而且我还发现一个经验之谈:如果你要判断某种“是否可达”的状态,是布尔值的那种判断,很大概率是可以考虑动态规划。而像这种“判断能不能拼接”其实就是个典型的可达性判断,它和“能不能跳到最后一个格子”或者“有没有路径从起点到终点”本质上是一样的。
这题也有扩展版本,比如不仅仅判断能不能拼,还要把所有可能的拆分结果都列出来,那就不止布尔值了,而是得返回所有路径,用回溯 + 记忆化搜索才能搞定。再比如如果加上最短路径要求,那也能往 BFS 上靠。
总之,这类题一开始看是字符串处理,其实最后考的还是你对状态转移的理解程度。
理解了之后,你写的是字符串,写的是数组,写的是图,套路都差不多。刷到这种题,我一般都挺开心的,因为逻辑清楚,代码整洁,而且能锻炼系统思维。
像我们平时搞业务代码,很多时候逻辑乱七八糟,但这种题你真写通了,会倒逼你养成“想清楚再动手”的习惯。
最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek
也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。