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

小哆啦刷力扣第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)

相关推荐
董董灿是个攻城狮3 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki4 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
qqxhb5 小时前
零基础数据结构与算法——第四章:基础算法-排序(上)
java·数据结构·算法·冒泡·插入·选择
FirstFrost --sy7 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
森焱森7 小时前
垂起固定翼无人机介绍
c语言·单片机·算法·架构·无人机
搂鱼1145147 小时前
(倍增)洛谷 P1613 跑路/P4155 国旗计划
算法
Yingye Zhu(HPXXZYY)7 小时前
Codeforces 2021 C Those Who Are With Us
数据结构·c++·算法
无聊的小坏坏9 小时前
三种方法详解最长回文子串问题
c++·算法·回文串
长路 ㅤ   9 小时前
Java后端技术博客汇总文档
分布式·算法·技术分享·编程学习·java后端
秋说9 小时前
【PTA数据结构 | C语言版】两枚硬币
c语言·数据结构·算法