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

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

相关推荐
新时代苦力工9 分钟前
桶排序-Java实现
数据结构·算法·排序算法
爱吃芒果的蘑菇1 小时前
Python读取获取波形图波谷/波峰
python·算法
晨曦学习日记1 小时前
Leetcode239:滑动窗口最大值,双端队列的实现!
数据结构·c++·算法
CoovallyAIHub1 小时前
无人机图像+深度学习:湖南农大团队实现稻瘟病分级检测84%准确率
深度学习·算法·计算机视觉
2zcode1 小时前
基于Matlab自适应阈值分割算法的图像处理研究
图像处理·算法·matlab
阿群今天学习了吗2 小时前
RNN、LSTM、Transformer推荐博文
人工智能·笔记·python·学习·算法
菥菥爱嘻嘻2 小时前
力扣面试150(42/150)
算法·leetcode·职场和发展
Morriser莫2 小时前
动态规划Day5学习心得
算法·动态规划
饭碗的彼岸one2 小时前
重生之我在10天内卷赢C++ - DAY 2
linux·开发语言·c++·笔记·算法·vim
Cando学算法3 小时前
AtCoder Beginner Contest 416(ABCDE)
c++·算法