15. 串联所有单词的子串
题目描述:
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好由 words 中所有单词串联组成的子串的起始索引。
解法(滑动窗口 + 哈希表):
算法思路
将每个单词视为一个整体字符,问题转化为寻找包含特定频次单词组合的区间。核心差异在于处理对象从字符变成了单词。
- 哈希表结构:使用
unordered_map<string, int>统计目标单词频次。 - 步长控制:左右指针移动步长为单词长度
len。 - 遍历次数:由于起始位置可能不同,需执行
len次滑动窗口遍历,确保不遗漏任何偏移量。
C++ 算法代码
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;
unordered_map<string, int> hash1; // 保存 words 里面所有单词的频次
for (auto &w : words) hash1[w]++;
int len = words[0].size(), m = words.size();
if (m == 0 || len == 0 || s.empty()) return ret;
// 执行 len 次,覆盖所有可能的起始偏移
for (int i = 0; i < len; i++) {
unordered_map<string, int> hash2; // 维护窗口内单词的频次
int count = 0;
for (int left = i, right = i; right + len <= s.size(); right += len) {
string in = s.(right, len);
hash2[in]++;
(hash(in) && hash2[in] <= hash1[in]) {
count++;
}
(right - left + > len * m) {
string out = s.(left, len);
(hash(out) && hash2[out] <= hash1[out]) {
count--;
}
hash2[out]--;
left += len;
}
(count == m) ret.(left);
}
}
ret;
}
};




