小哆啦解题记——字符拼图

小哆啦刷力扣第31天

383. 赎金信 - 力扣(LeetCode)

第一章:离奇的字母饼干失窃案

大雄的课桌上散落着几块字母饼干,拼出"HELP"的字样。"这一定是胖虎干的!"他握着半块残缺的'e'饼干哀嚎,"他说要用magazine饼干拼出'HELL'勒索我!"

哆啦A梦掏出一包铜锣烧,幽幽道:"先别急着哭。你现在有magazine饼干库存'aabcd',胖虎要的ransomNote是'abcc'。你猜缺了哪个字母?"

大雄掰着手指:"a、b、c...第三个c!我的magazine里只有1个c!"

"很好,"哆啦A梦露出狡黠的笑容,"现在,我们要用算法证明胖虎偷吃了c饼干!"


第二章:暴力搜查队的惨败

大雄自告奋勇掏出"枚举放大镜":

typescript 复制代码
function naiveCanConstruct(ransom: string, mag: string): boolean {  
    let magazine = mag.split('');  
    for (let char of ransom) {  
        const pos = magazine.indexOf(char);  
        if (pos === -1) return false;  
        magazine.splice(pos, 1); // 找到一块就掰碎一块  
    }  
    return true;  
}  

当测试naiveCanConstruct("abcc", "aabcd")时,程序突然发出刺耳的警报------原来每次splice都像让大雄在操场上翻找被踩碎的饼干渣,时间复杂度**O(n²)**让CPU风扇疯狂旋转,电脑屏幕飘出焦香。


第三章:哈希神枪手的降维打击

哆啦A梦从四次元口袋掏出一把造型奇特的枪:"试试这个------频率扫描枪!"

作战计划

  1. 建立字母雷达:26格特制弹夹对应a-z
  2. 扫描magazine军火库:每发现一个字母,对应弹夹+1
  3. 发动反攻:对ransomNote每个字母开火,弹夹-1。若弹夹打空则宣告失败
typescript 复制代码
function hashGunCanConstruct(ransomNote: string, magazine: string): boolean {  
    const bulletCase = new Array(26).fill(0);  
    // 填装弹药  
    for (const char of magazine) {  
        bulletCase[char.charCodeAt(0) - 97]++;  
    }  
    // 精确打击  
    for (const char of ransomNote) {  
        const idx = char.charCodeAt(0) - 97;  
        if (--bulletCase[idx] < 0) {  
            console.log(`警报!${char}弹药不足!`);  
            return false;  
        }  
    }  
    return true;  
}  

当测试hashGunCanConstruct("abcc", "aabcd")时,控制台突然喷出彩色烟雾弹:"警报!c弹药不足!"。大雄激动地发现------子弹轨迹可视化让问题无所遁形!


第四章:时空特工の绝地反击

就在众人欢呼时,胖虎发来挑衅视频:"哈哈哈哈,我用时光机复制了100万个c饼干!你的破数组只能存到2^32-1,等着崩溃吧!"

哆啦A梦冷笑一声,按下枪柄上的隐藏按钮:"启动BigInt模式!"

typescript 复制代码
bulletCase[22] = 9999999999999999999999999999999n; // 'w'字母的计数突破天际  

大雄突然发现华点:"等等!如果我们遇到的不是字母而是🦄这样的Emoji..."

哆啦A梦甩出一个泛型函数:

typescript 复制代码
function universalCanConstruct<T extends string>(ransom: T, mag: T): boolean {  
    const frequencyMap = new Map<string, number>();  
    // 宇宙级字符统计  
    for (const char of mag) {  
        frequencyMap.set(char, (frequencyMap.get(char) || 0) + 1);  
    }  
    // 降维打击  
    for (const char of ransom) {  
        const count = frequencyMap.get(char) || 0;  
        if (count <= 0) return false;  
        frequencyMap.set(char, count - 1);  
    }  
    return true;  
}  

"现在连外星文字都能统计了!"哆啦A梦得意地咬了一口铜锣烧。


终章:算法与饼干の哲学

当胖虎在铁证如山前认罪时,静香悄悄告诉大雄:"其实...我吃掉的那个'e',是想测试你的解题速度。"

技术启示录

  1. 空间换时间:哈希表像哆啦A梦的口袋,牺牲少量空间换取极致速度
  2. 预处理思维:先扫描magazine如同战前清点弹药,避免战时手忙脚乱
  3. 扩展性设计:用Map替代数组,如同给算法装上任意门

大雄望着星空感叹:"原来每一个算法,都是时空管理者写给计算机的浪漫情书啊..."

(窗外传来胖虎的怒吼:"谁把我的'c'饼干写成'C'了?大小写敏感怎么不说清楚!")

相关推荐
松涛和鸣1 小时前
11.C 语言学习:递归、宏定义、预处理、汉诺塔、Fibonacci 等
linux·c语言·开发语言·学习·算法·排序算法
2501_941111242 小时前
C++与自动驾驶系统
开发语言·c++·算法
2501_941111693 小时前
C++中的枚举类高级用法
开发语言·c++·算法
jz_ddk3 小时前
[算法] 算法PK:LMS与RLS的对比研究
人工智能·神经网络·算法·信号处理·lms·rls·自适应滤波
Miraitowa_cheems3 小时前
LeetCode算法日记 - Day 106: 两个字符串的最小ASCII删除和
java·数据结构·算法·leetcode·深度优先
旭编3 小时前
小红的好矩形
c++·算法
小白程序员成长日记3 小时前
2025.11.12 力扣每日一题
算法·leetcode·职场和发展
Alex艾力的IT数字空间3 小时前
设计既保持高性能又兼顾可移植性的跨平台数据结构
数据结构·分布式·算法·微服务·中间件·架构·动态规划
leoufung3 小时前
贪心算法核心定理与应用——以 Gas Station 问题为例
算法·贪心算法
2501_941111464 小时前
C++与硬件交互编程
开发语言·c++·算法