笑死,朋友被岳父嫌弃是码农,要求回家考体制才同意,朋友在鹅厂。。
刚看到个贴子说,一个在鹅厂上班的程序员,竟然被岳父嫌弃是码农,非要他辞职考公才肯同意婚事,网友们也是笑疯了。
我觉得这事吧,说到底还是“认知差异”。在很多长辈眼里,“体制内”=稳定+体面+有保障,而“码农”=996+猝死新闻+不靠谱。
可问题是,现在大厂程序员的收入和发展路径,早就不是老一辈认知里的“打工仔”了。
不过话说回来,既然是要成一家人,沟通还是得有的。比起怄气,不如好好“科普”一把,毕竟认同感和安全感,不只来自编制,也来自靠谱人。
【备注:文末可领最新资料】
算法题:解码方法
“解码方法”这道题吧,说实话,看着挺唬人的,但其实就是个递归+动态规划的经典老题。题面大概是:给你一个只包含数字的字符串,比如 "226",每个数字可以按 '1' -> 'A', '2' -> 'B' ... '26' -> 'Z' 去解码,问你一共有多少种不同的解码方式。
听着像什么 AI 算法要起飞,其实就是个变种的爬楼梯问题。你可以从前往后扫一遍,dp搞一搞,逻辑就清清楚楚了。
我一般喜欢从递归开始理解。你想啊,解码“226”的时候,其实就是考虑:
前一个字符单独拿出来,比如 '2',那剩下“26”交给递归去搞 前两个字符一起拿出来,比如 '22',如果 <=26 的话,也可以一起组成一个字母,那剩下的“6”交给递归
看着就像这样:
intnumDecodings(String s){
if (s == null || s.length() == 0) return0;
return dfs(s, 0);
}
intdfs(String s, int index){
if (index == s.length()) return1; // 说明走到头了,是一种解法
if (s.charAt(index) == '0') return0; // '0' 开头没法解码
int res = dfs(s, index + 1); // 只解一个字符
if (index + 1 < s.length()) {
int twoDigit = Integer.parseInt(s.substring(index, index + 2));
if (twoDigit >= 10 && twoDigit <= 26) {
res += dfs(s, index + 2); // 解两个字符
}
}
return res;
}
但是这玩意儿递归写法说实话,性能那叫一个拉胯,你每层都重复计算一堆重复子问题,跑大数据直接GG🤯
所以标准解法当然是用DP优化了——经典套路:dp[i] 表示前 i 个字符的解码方式总数。然后就是状态转移方程搞一下:
publicintnumDecodings(String s){
if (s == null || s.length() == 0 || s.charAt(0) == '0') return0;
int n = s.length();
int[] dp = newint[n + 1];
dp[0] = 1; // 空字符串一种解码方式
dp[1] = 1; // 第一个字符不是0就是一种解码方式
for (int i = 2; i <= n; i++) {
char one = s.charAt(i - 1);
char two = s.charAt(i - 2);
if (one != '0') {
dp[i] += dp[i - 1]; // 单字符合法
}
int num = (two - '0') * 10 + (one - '0');
if (num >= 10 && num <= 26) {
dp[i] += dp[i - 2]; // 两字符合法
}
}
return dp[n];
}
你看这写法,逻辑清晰,空间复杂度 O(n),时间复杂度也是 O(n),处理“226”这种输入,输出直接是 3(BZ、VF、BBF)。
你要非得优化点空间,其实用两个变量滚动也能做,省个数组空间。但除非你真卡内存,不然还不如清晰点。
讲真,这道题除了锻炼你递归和DP的基本功,还有个隐含思路就是边界处理——比如字符串里有个“0”的时候怎么办,"06"算不算合法?能不能和前面的组合?这些细节是面试官专挑你不会的地方问😏
所以这道题要总结经验就是:
✅ 先从递归理解问题 ✅ 然后加缓存(记忆化)优化 ✅ 最后搞成动态规划,注意初始化和边界条件
说到底,不管是爬楼梯还是解码,这类题的本质就是“当前的解法数 = 前一步数 + 前两步数”,这不就是斐波那契变种嘛!
兄弟们,背熟这个模式,去面试基本能横着走了。💪
最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek
-END-