15. 串联所有单词的子串
题目描述
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
解题思路
这道题的核心在于将每个单词视为一个整体字符,问题转化为寻找包含特定词频的异位词子串。
关键点:
- 哈希表统计 words 中每个单词的出现频次。
- 滑动窗口的步长固定为单词长度 len。
- 由于起始位置可能不是单词长度的倍数,需要遍历 0 到 len-1 作为初始偏移量,每轮重置哈希表。
C++ 代码实现
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;
unordered_map<string, int> hash1; // 统计目标单词频次
for (auto e : words) {
hash1[e]++;
}
int len = words[0].size();
int m = words.size();
int n = s.size();
// 从 0 到 len-1 分别作为起始偏移量
for (int i = 0; i < len; i++) {
unordered_map<string, int> hash2; // 当前窗口内单词频次
int count = 0; // 有效单词数
int left = i;
// 每次移动 len 步长
for (int right = i; right + len <= n; right += len) {
string str1 = s.substr(right, len);
hash2[str1]++;
if (hash2[str1] <= hash1[str1]) {
count++;
}
(right - left + > len * m) {
string str2 = s.(left, len);
(hash2[str2] <= hash1[str2]) {
count--;
}
hash2[str2]--;
left += len;
}
(count == m) {
ret.(left);
}
}
}
ret;
}
};


