马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
碎碎念
这是我在2024年12月21日的算法训练,加油!
标题一:不常见单词查找
884. 两句话中的不常见单词
标题描述
给定两个句子 s1 和 s2,找出仅在此中一个句子中出现一次的单词。也就是说,这些单词在两个句子中只出现过一次,并且只出如今此中一个句子中。
示例
示例 1:
- 输入: s1 = "this apple is sweet", s2 = "this apple is sour"
- 输出: ["sweet","sour"]
复制代码 示例 2:
- 输入: s1 = "apple apple", s2 = "banana"
- 输出: ["banana"]
复制代码 解题思绪
- 字符串分割
- 使用 C++ 的 istringstream 进行字符串分割,根据 C++ Reference 文档,这是处理空格分隔字符串的标准方法。
- istringstream 会自动跳过空格,逐个读取单词。
- 通过将两个句子分开处理,可以准确统计每个单词的总出现次数。
- 词频统计
- 使用 unordered_map 记录每个单词的出现次数。
- 遍历两个句子中的所有单词,并在哈希表中更新对应单词的计数。
- 时间复杂度为 O(n),此中 n 为总单词数。
- 空间复杂度为 O(m),此中 m 为不重复单词数。
- 结果筛选
- 遍历哈希表,筛选出出现次数为 1 的单词,这些单词即为仅在一个句子中出现过的单词。
完备代码实现
- #include <vector>
- #include <string>
- #include <unordered_map>
- #include <sstream>
- using namespace std;
- class Solution {
- public:
- vector<string> uncommonFromSentences(string s1, string s2) {
- unordered_map<string, int> wordsCount; // 哈希表用于记录单词频率
- string word;
- vector<string> result;
- // Lambda 函数用于处理字符串分割和词频统计
- auto helper = [&](const string& s) {
- istringstream iss(s);
- while (iss >> word) {
- wordsCount[word]++;
- }
- };
- helper(s1); // 处理第一个句子
- helper(s2); // 处理第二个句子
- // 筛选出只出现一次的单词
- for (const auto& [key, value] : wordsCount) {
- if (value == 1) {
- result.emplace_back(key);
- }
- }
- return result;
- }
- };
复制代码 代码剖析
- unordered_map<string, int> wordsCount: 用于存储每个单词及其出现次数。
- helper Lambda 函数: 负责将输入的句子进行分割,并更新哈希表中的单词计数。
- 遍历哈希表: 通过遍历哈希表中的键值对,筛选出出现次数为 1 的单词,并将其添加到结果向量中。
时间复杂度分析
- 字符串分割: 每个句子都必要 O(n) 的时间进行分割。
- 词频统计: 由于使用了哈希表,插入和查找操作的匀称时间复杂度为 O(1),总的词频统计时间复杂度为 O(n)。
- 结果筛选: 遍历哈希表,时间复杂度为 O(m)。
总体时间复杂度为 O(n),此中 n 是两个句子中单词的总数。
标题二:字符串压缩
口试题 01.06. 字符串压缩
标题描述
实现一个方法,将一连重复的字符进行压缩。对于每一组一连重复的字符,替换成字符后跟其出现的次数。假如压缩后的字符串没有变短,则返回原始字符串。
示例
示例 1:
- 输入:"aabcccccaaa"
- 输出:"a2b1c5a3"
复制代码 示例 2:
解题思绪
使用双指针技巧解决该题目:
- 指针设计
- i 指针:标志当前处理字符的起始位置。
- j 指针:向后搜索相同字符的结束位置。
- 区间 [i, j) 表示一连相同字符段。
- 压缩规则
- 记录每段相同字符的首字符和出现次数。
- 当压缩后字符串更短时返回压缩后的字符串,否则返回原字符串。
- 时间复杂度为 O(n),此中 n 是字符串的长度。
- 空间复杂度为 O(n),用于存储压缩后的字符串。
- 优化点
- 预先计算压缩后的字符串长度,可以避免在不必要的环境下进行字符串拼接。
- 使用 ostringstream 或者直接构造字符串以提升效率。
完备实现
- #include <string>
- using namespace std;
- class Solution {
- public:
- string compressString(string S) {
- int i = 0, j = 0;
- string result;
- while (i < S.size()) {
- // 移动 j 指针,找到当前字符段的结束位置
- while (j < S.size() && S[i] == S[j]) {
- j++;
- }
- // 记录当前字符及其出现次数
- result += S[i];
- result += to_string(j - i);
- i = j; // 更新 i 指针,开始处理下一个字符段
- }
- // 比较压缩后的字符串长度与原字符串的长度
- return result.size() < S.size() ? result : S;
- }
- };
复制代码 代码剖析
- 指针 i 和 j: 用于标志当前正在处理的字符段的起始和结束位置。
- 字符串拼接: 将当前字符和其出现次数拼接到结果字符串中。
- 条件判断: 最后比较压缩后的字符串长度与原字符串长度,决定返回哪一个。
时间复杂度分析
- 主循环: 每个字符最多被遍历两次(一次由 i 指针,一次由 j 指针),时间复杂度为 O(n)。
- 字符串拼接: 在最坏环境下,每个字符都必要被拼接到结果字符串中,依然保持 O(n) 的时间复杂度。
总体时间复杂度为 O(n),空间复杂度为 O(n)。
进一步优化
- 假如必要进步性能,可以思量预分配充足的空间给 result 字符串,避免多次内存分配。
- 在处理大量重复字符时,可以提前返回结果,减少不必要的计算。
总结
本日的两题也优劣常简朴的两题,主要观察了字符串处理的根本技巧。加油喔!
附加资源
- C++ istringstream 使用指南
- LeetCode 884. 两句话中的不常见单词 题解
- LeetCode 口试题 01.06. 字符串压缩 解题思绪
- 双指针算法详解
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |