)
文档教程知识库【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/forthespada/InterviewGuide点击查看免费下载本篇是 InterviewGuide 仓库「精选力扣 300 题目之哈希表」Easy 分类下第 884 题的完整题解。围绕「不常见单词」的定义本文会讲清楚如何把计数问题翻译成哈希表统计词频给出仓库中原始记录的手写 C 解法并逐行剖析其切词与边界处理细节最后补充更简洁的istringstream写法并串联哈希表分类下的同类题目供刷题时对照复习。读完本文你将掌握「用unordered_map统计词频、再按频次筛选」这一类题目的标准套路以及面试手撕时需要注意的边界条件。题目回顾什么是不常见单词给定两个句子 A 和 B句子是一串由空格分隔的单词每个单词仅由小写字母组成如果一个单词在其中一个句子中只出现一次在另一个句子中却没有出现那么这个单词就是不常见的要求返回所有不常见单词的列表顺序不限。原始题解记录见 884.两句话中的不常见单词.md本文以此文档为主体展开。示例与约束示例 1输入A this apple is sweetB this apple is sour输出[sweet,sour]。其中this、apple、is都在两句中重复出现而sweet只在 A 中、sour只在 B 中。示例 2输入A apple appleB banana输出[banana]。apple虽然在 A 中出现了两次但既然它「出现不止一次」就不满足「只出现一次」的条件因此不是不常见单词。提示0 A.length 2000 B.length 200A 和 B 都只包含空格和小写字母。题目允许句子为空串长度可为 0这是后面实现中必须处理好的边界情况。解题思路把「不常见」翻译成「全局词频 1」本题看似在说「一个句子出现一次、另一个句子不出现」但如果把两句话合并看待条件可以等价改写为一个单词在 A、B 两个句子合并后的总词频中恰好只出现 1 次。原因很简单若单词只在一句话里出现一次另一句没有 → 合并后总频次为 1若单词在两句话里总共出现 2 次及以上无论是同一句内重复还是跨句重复→ 不满足「只出现一次」应被排除示例 2 中apple apple里的apple总频次为 2即使另一句没有也不符合条件。因此解题分为两步统计用一个哈希表C 的unordered_mapstring, int对两个句子中的所有单词分别计数筛选遍历哈希表取出所有value 1的键即单词本身放入结果数组返回。这一步的筛选是unordered_map最适合干的活——它以哈希方式组织键值插入和查询都是平均 O(1) 的复杂度且遍历时可以直接拿到「单词 → 出现次数」的完整对应关系。第一版实现仓库中记录的手写切词 unordered_map 统计原文档给出的第一版解法完全沿用了上述思路且没有借助split之类的库函数而是手动按空格切词代码如下vectorstring uncommonFromSentences(string A, string B) { unordered_mapstring,int un_mp; string temp; for (unsigned i0;iA.size();i) { temp ; while (A[i] ! i A.size()) { temp A[i]; } if (temp.size() 0) un_mp[temp]; } for (unsigned i 0; i B.size(); i) { temp ; while (B[i] ! i B.size()) { temp B[i]; } if (temp.size() 0) un_mp[temp]; } vectorstring res; for (auto a : un_mp) { if (a.second 1) res.push_back(a.first); //cout a.first a.second endl; } return res; }原文档记录了该版本提交时的表现历史提交数据来自 LeetCode 中文站执行用时4 ms击败约 91.83% 的 cpp 提交内存消耗8.7 MB击败约 100.00% 的提交。这段代码虽然「土」但在面试手撕场景下非常直观两次遍历分词、一次遍历筛词全程只用到一个unordered_mapstring, int空间占用只有「不同单词的个数」。逐行拆解手写切词的细节核心的切词循环是while (A[i] ! i A.size()) { temp A[i]; }这里有两个容易被忽略的细节循环条件的先后顺序先判断A[i] ! 再判断i A.size()。当i已经等于size()即扫描到字符串末尾之后时C 标准保证string::operator[]在i size()位置返回一个指向空字符\0的引用\0 ! 为真紧接着i A.size()为假循环安全退出不会越界访问。也就是说这种写法依赖「\0不等于空格」这一事实来兜底收尾。跳过空串if (temp.size() 0) un_mp[temp];保证即使句子中出现连续空格虽然题目约束下不会出现也不会把空串计入统计。同时在循环外层for的末尾i已经指向空格位置下一轮外层循环会i跳过该空格再进入下一轮切词。对 B 的第二次遍历与 A 完全对称。最终遍历哈希表时a.first是单词、a.second是出现次数只收集a.second 1的单词即可。由于unordered_map本身无序返回结果天然满足题目「可以按任何顺序返回列表」的要求。复杂度分析时间复杂度O(n)其中 n 为两个句子字符总长度。两轮分词各自线性扫描一遍句子最后一轮遍历哈希表也只需 O(k)k 为不同单词数总体为线性时间。空间复杂度O(k)k 为 A 和 B 中出现的不同单词总数哈希表只存储不重复的键值对。进阶写法用 istringstream 简化分词手写切词能帮助我们理解指针/下标推进的细节但生产级代码通常直接交给std::istringstream来做「按空格分词」代码更短、更不易出错#include sstream vectorstring uncommonFromSentences(string A, string B) { unordered_mapstring, int un_mp; istringstream iss(A B); // 合并两句话统一分词统计 string word; while (iss word) { un_mp[word]; } vectorstring res; for (auto it : un_mp) { if (it.second 1) res.push_back(it.first); } return res; }这里的改进点在于用A B把两句话拼成一句中间补一个空格之后一次while (iss word)就能把两个句子的所有单词全部喂进同一个哈希表免去了对 A、B 各写一遍的重复代码operator天然按空白符含空格切分且会自动跳过空串与第一版里temp.size() 0的判断效果一致统计与筛选两个阶段的结构保持不变逻辑与第一版完全等价只是实现更简洁。面试延伸哈希表分类下的同类题目串联「统计词频 → 按条件筛选」是哈希表分类下的高频套路本仓库哈希表模块中还收录了多道可对照练习的题目题目核心考点仓库路径387. 字符串中的第一个唯一字符用哈希表统计字符频次再按字符串顺序找第一个频次为 1 的字符easy/387.字符串中的第一个唯一字符.md1207. 独一无二的出现次数哈希表统计频次后再用unordered_set判断频次是否互不相同easy/1207.独一无二的出现次数.md290. 单词规律用两张哈希表建立字符↔单词的双向映射easy/290.单词规律.md205. 同构字符串字符之间双向映射判断是否一一对应easy/205.同构字符串.md970. 强整数用unordered_set完成去重再转成vector返回easy/970.强整数.md尤其值得对比的是 1207 题与本题1207 统计的是数字的出现次数再用unordered_set判重返回un_st.size() un_mp.size()本题统计的是单词的出现次数再按value 1筛选。两者共用同一套「哈希表计数」骨架只是筛选条件不同。刷题时可以把它们放在一起对照强化「统计 → 筛选」两步走的心智模型。小结不常见单词 合并后全局词频恰好为 1 的单词这是把题意转化为哈希表问题的关键一步实现上「手写切词 unordered_mapstring, int」与「istringstream分词」两种写法等价前者适合理解边界细节后者适合快速写出干净代码注意两个边界句子可能为空串长度 0以及切词循环中\0 ! 对越界收尾的兜底本题位于哈希表分类的 Easy 档与之相邻的 387、1207、290、205、970 等题目均可在 05-哈希表 目录下找到完整题解是面试前复习哈希表套路的高性价比组合。赞分享文档教程知识库【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/forthespada/InterviewGuide点击查看免费下载相关推荐LogicStack-LeetCode 题解884. 两句话中的不常见单词哈希表 模拟LogicStack LeetCode 题解884. 两句话中的不常见单词哈希表 模拟 本文以 LogicStack LeetCode 仓库中 884教程文档两句话中的不常见单词NeetCode 哈希表计数解法全解析两句话中的不常见单词NeetCode 哈希表计数解法全解析 本篇技术指南聚焦 LeetCode 经典题目「Uncommon Words from Two Se示例工程教程AlgoNote 题解0884. 两句话中的不常见单词——用哈希表统计词频的字符串计数实战AlgoNote 题解0884. 两句话中的不常见单词——用哈希表统计词频的字符串计数实战 本篇是「算法通关手册」AlgoNote LeetCode 题解教程文档知识库上一篇如何在离线环境下使用Osintgram进行Instagram数据分析完整指南下一篇stdexec性能优化从入门到专家的完整调优指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考