昨天还在说没对象,今天工作都没了。 那我有什么?有房贷啊,还有一身过劳的臭毛病。
昨天还在群里哀嚎“没对象”,今天工牌都刷不开了,这剧情比相亲市场还狠。对象没着落,工作先黄了,成年人的安全感真是一天比一天抽象。
最扎心的是,人家问你“那你现在还有什么”,你都不好意思沉默太久。有什么?有房贷。有花呗。有凌晨两点还睡不着的职业病。还有一身坐出来的腰疼、颈椎疼、脾气越来越差的臭毛病。恋爱没谈明白,班倒是先白加了。
你说职场给了我们什么,工资像安慰奖,压力像包月服务。年轻时候觉得熬一熬就过去了,熬到后面才发现,过去的是自己。最稳定的关系,可能真就是每个月那条还款短信。
面试题:金字塔转换矩阵
这题第一眼看着像回溯,真写起来,坑基本都在“怎么把下一层候选快速拿出来”这一步。题目给你一行底边,比如 BCD,再给一批三元规则,像 BCG、CDE 这种,意思是底下相邻两个字母如果是 BC,上面可以放 G。最后问一句,这个金字塔能不能一路往上搭到只剩一个字符。这个题要是上来就硬搜,分支一多,递归树马上就炸。真正该先做的,不是递归,而是先把规则表收拾干净。这个取舍就很关键,跟线上排查一个味道:先把索引建好,再谈扫描。整体写法我参考了那种“先落现象,再给关键判断”的技术表达气质,但内容和代码都是重新写的。
这题我一般先把 allowed 转成 Map<String, List<Character>>。比如 BCG 和 BCA,就记成 BC -> [G, A]。后面递归时,拿到底层相邻两个字符,直接查表,不要每次都去全表里扫。
代码别写得太教学,我贴现场能过题的关键版本:
import java.util.*;
publicclassSolution{
publicbooleanpyramidTransition(String bottom, List<String> allowed){
Map<String, List<Character>> ruleMap = new HashMap<>();
for (String s : allowed) {
String key = s.substring(0, 2);
ruleMap.computeIfAbsent(key, k -> new ArrayList<>()).add(s.charAt(2));
}
return dfs(bottom, ruleMap, new HashMap<>());
}
privatebooleandfs(String row, Map<String, List<Character>> ruleMap, Map<String, Boolean> memo){
if (row.length() == 1) {
returntrue;
}
if (memo.containsKey(row)) {
return memo.get(row);
}
List<String> nextRows = new ArrayList<>();
buildNextRows(row, 0, new StringBuilder(), nextRows, ruleMap);
for (String next : nextRows) {
if (dfs(next, ruleMap, memo)) {
memo.put(row, true);
returntrue;
}
}
memo.put(row, false);
returnfalse;
}
privatevoidbuildNextRows(String row, int idx, StringBuilder path,
List<String> nextRows, Map<String, List<Character>> ruleMap){
if (idx == row.length() - 1) {
nextRows.add(path.toString());
return;
}
String key = row.substring(idx, idx + 2);
List<Character> list = ruleMap.get(key);
if (list == null) {
return;
}
for (char ch : list) {
path.append(ch);
buildNextRows(row, idx + 1, path, nextRows, ruleMap);
path.deleteCharAt(path.length() - 1);
}
}
}
这版代码核心就两件事。
一个是预处理规则,不让递归阶段做重复劳动。另一个是记忆化,某一层字符串如果已经判过走不通,别再回来撞第二次。很多人卡超时,不是回溯不会写,是没做这层缓存。
再说下判断顺序。假设当前层是 BCD,那下一层的第一个位置来自 BC,第二个位置来自 CD。所以这一层其实不是只生成一个结果,而是把每个位置的候选做组合。这里最容易写歪的地方,是有人在生成下一层时,拿到一个可用字符就直接往下递归,结果把同层剩余位置漏掉了。