小哆啦解题记——映射的背叛

小哆啦刷力扣第32天

✉️ 题目:205. 同构字符串 - 力扣(LeetCode)


第一章:字符的恋爱脑

"哆啦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 → ad → b,但 b 同时被 ad 盯上了------字符之间出现了背叛!"


第二章:爱情不能重婚

胖虎突然闯进房间,戴着墨镜,端着电动风扇,假装法官:"小子,你违反了映射一夫一妻制!你需要判刑!"

大雄连忙认错:"我确实只关心了 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→ta→ie→l,都对了,但是你让 r→e 又想让 p 再映射 e?你这是复婚失败!"

静香轻声说:"其实,我早就知道你能搞懂,只是想看看你什么时候发现算法的温柔。"

铜锣烧的香气中,大雄望着屏幕上两个字符数组缓缓对齐,轻声道:

"原来所谓同构,不过是字符之间不忘初心、各守其主的誓言啊。"

(窗外传来胖虎的怒吼:"为什么不能让我 a → bb → b 啊!b 又不是你家的!")


🔍 技术启示录

  • 双向映射判定是核心关键:只检查一边是片面的,关系是要"你中有我,我中有你"。
  • Map/Set 优于对象/数组 :支持任意键,避免编码陷阱(如 charCodeAt 的 Unicode 陷阱)。
  • Unicode与Emoji的容错性 :想支持🦄与🐍?请用 Map<string, string>,别想着用数组下标。
  • 抽象思维:字符映射 = 函数单射(injective function)

相关推荐
.YM.Z14 分钟前
【数据结构】:排序(一)
数据结构·算法·排序算法
Chat_zhanggong34517 分钟前
K4A8G165WC-BITD产品推荐
人工智能·嵌入式硬件·算法
百***480732 分钟前
【Golang】slice切片
开发语言·算法·golang
墨染点香1 小时前
LeetCode 刷题【172. 阶乘后的零】
算法·leetcode·职场和发展
做怪小疯子1 小时前
LeetCode 热题 100——链表——反转链表
算法·leetcode·链表
做怪小疯子3 小时前
LeetCode 热题 100——矩阵——旋转图像
算法·leetcode·矩阵
努力学习的小廉3 小时前
我爱学算法之—— BFS之最短路径问题
算法·宽度优先
高山上有一只小老虎3 小时前
构造A+B
java·算法
木头左3 小时前
缺失值插补策略比较线性回归vs.相邻填充在LSTM输入层的性能差异分析
算法·线性回归·lstm
sin_hielo4 小时前
leetcode 2435
数据结构·算法·leetcode