小哆啦刷力扣第32天
第一章:字符的恋爱脑
"哆啦A梦!我好像发现了恋爱规律!"
大雄手里拿着两张纸条,一张写着 "badc"
,一张写着 "baba"
。他义正词严地宣布:"我觉得这两个字符串是一对灵魂伴侣!"
哆啦A梦瞥了一眼,叹了口铜锣烧的热气:"你是说,每个字符都找到了它命中注定的另一半?"
"对啊!我写了段代码,检查每个 s[i]
有没有和 t[i]
坚贞不渝地走到最后!"
大雄自信地贴出代码:
vbnet
function isIsomorphic(s: string, t: string): boolean {
let arrMap = new Map<string, string>();
if (s.length !== t.length) return false;
for (let i = 0; i < s.length; i++) {
if (arrMap.has(s[i])) {
if (arrMap.get(s[i]) !== t[i]) return false;
} else {
arrMap.set(s[i], t[i]);
}
}
return true;
}
"完美!"他按下运行键,结果返回:true
。
哆啦A梦眉头一皱:"你试试 'badc'
和 'baba'
。"
测试结果依然是 true
。
哆啦一拍大腿:"大事不妙!你这不是一对一,是多人运动 !你看看 a → a
,d → b
,但 b
同时被 a
和 d
盯上了------字符之间出现了背叛!"
第二章:爱情不能重婚
胖虎突然闯进房间,戴着墨镜,端着电动风扇,假装法官:"小子,你违反了映射一夫一妻制!你需要判刑!"
大雄连忙认错:"我确实只关心了 s → t
,但忘了看 t
有没有早就被别人占用了。"
于是他修正代码,加上"已婚字符登记簿":
vbnet
function isIsomorphic(s: string, t: string): boolean {
let strtMap = new Map<string, string>();
let usedChars = new Set<string>();
if (s.length !== t.length) return false;
for (let i = 0; i < s.length; i++) {
const sc = s[i], tc = t[i];
if (strtMap.has(sc)) {
if (strtMap.get(sc) !== tc) return false;
} else {
if (usedChars.has(tc)) return false;
strtMap.set(sc, tc);
usedChars.add(tc);
}
}
return true;
}
"这下不可能出现一个 b
被两个 s
字符追着跑了。"大雄自豪地说。
第三章:双向绑定の誓约仪式
"你觉得这就完了吗?"哆啦A梦眯起眼,"在算法世界里,唯一的忠诚不是单向的,是双向绑定。"
他啪地打开一扇任意门,带着大雄进入字符婚姻登记局------
每对字符结婚,都要双向签约。否则就算一方没出轨,另一方可能偷偷搞小动作。
于是,大雄再次进化代码:
vbnet
function isIsomorphic(s: string, t: string): boolean {
const s2t = new Map<string, string>();
const t2s = new Map<string, string>();
for (let i = 0; i < s.length; i++) {
const sc = s[i], tc = t[i];
if ((s2t.has(sc) && s2t.get(sc) !== tc) ||
(t2s.has(tc) && t2s.get(tc) !== sc)) {
return false;
}
s2t.set(sc, tc);
t2s.set(tc, sc);
}
return true;
}
胖虎坐在角落冷哼一声:"一夫一妻双向绑定,真保守。"
"但足够稳定。"静香微笑着递上一杯热茶。
第四章:V8引擎的映射失控实验
"不过哆啦,"大雄低声问,"如果我把 s
换成十万个🦄,每个都映射成不同的Emoji,会崩吗?"
哆啦掏出调试仪:"我们进入底层看看。"
💡 深入V8引擎内幕时间:
- 字符串底层会被转换为 UTF-16 编码单元处理;
- JavaScript 的 Map 实现是基于哈希表,甚至可接受 Emoji、汉字、甚至混合语言键;
- 只要映射关系 O(1) 插入查询就不会崩溃,但需要注意空间增长。
"大雄,"哆啦A梦拍了拍他,"你如果用 Emoji 编表,就不要用数组那种索引结构,Map
就是你宇宙级的任意门。"
终章:算法は契约の魔法
当胖虎最终试图用 'paper'
和 'title'
骗婚失败时,被大雄一顿打脸:"p→t
,a→i
,e→l
,都对了,但是你让 r→e
又想让 p
再映射 e
?你这是复婚失败!"
静香轻声说:"其实,我早就知道你能搞懂,只是想看看你什么时候发现算法的温柔。"
铜锣烧的香气中,大雄望着屏幕上两个字符数组缓缓对齐,轻声道:
"原来所谓同构,不过是字符之间不忘初心、各守其主的誓言啊。"
(窗外传来胖虎的怒吼:"为什么不能让我 a → b
,b → b
啊!b 又不是你家的!")
🔍 技术启示录
- ✅ 双向映射判定是核心关键:只检查一边是片面的,关系是要"你中有我,我中有你"。
- ✅ Map/Set 优于对象/数组 :支持任意键,避免编码陷阱(如
charCodeAt
的 Unicode 陷阱)。 - ✅ Unicode与Emoji的容错性 :想支持🦄与🐍?请用
Map<string, string>
,别想着用数组下标。 - ✅ 抽象思维:字符映射 = 函数单射(injective function)