题目描述:
https://leetcode.com/problems/substring-with-concatenation-of-all-words/
解决方案:
https://leetcode.windliang.cc/leetCode-30-Substring-with-Concatenation-of-All-Words.html
mycode(c++):
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words){
vector<int> res ;
int wordNum = words.size();
if (wordNum == 0) {
return res;
}
int wordLen = words[0].length();
map<string, int> allWords ;
for (string w : words) {
if(allWords.count(w))
allWords[w] = allWords[w] + 1;
else
allWords[w] = 0;
}
//将所有移动分成 wordLen 类情况
for (int j = 0; j < wordLen; j++) {
map<string, int> hasWords ;
int num = 0; //记录当前 HashMap2(这里的 hasWords 变量)中有多少个单词
//每次移动一个单词长度
for (int i = j; i < s.length() - wordNum * wordLen + 1; i = i + wordLen) {
bool hasRemoved = false; //防止情况三移除后,情况一继续移除
while (num < wordNum) {
string word = s.substr(i + num * wordLen, wordLen);
if (allWords.count(word)) {
if(hasWords.count(word))
hasWords[word]= hasWords[word] + 1;
else
hasWords[word] = 0;
//出现情况三,遇到了符合的单词,但是次数超了
if (hasWords[word] > allWords[word]) {
// hasWords.put(word, value);
hasRemoved = true;
int removeNum = 0;
//一直移除单词,直到次数符合了
while (hasWords[word] > allWords[word]) {
string firstWord = s.substr(i + removeNum * wordLen, wordLen);
int v = hasWords[firstWord];
hasWords[firstWord]= v - 1;
removeNum++;
}
num = num - removeNum + 1; //加 1 是因为我们把当前单词加入到了 HashMap 2 中
i = i + (removeNum - 1) * wordLen; //这里依旧是考虑到了最外层的 for 循环,看情况二的解释
break;
}
//出现情况二,遇到了不匹配的单词,直接将 i 移动到该单词的后边(但其实这里
//只是移动到了出现问题单词的地方,因为最外层有 for 循环, i 还会移动一个单词
//然后刚好就移动到了单词后边)
} else {
hasWords.clear();
i = i + num * wordLen;
num = 0;
break;
}
num++;
}
if (num == wordNum) {
res.push_back(i);
}
//出现情况一,子串完全匹配,我们将上一个子串的第一个单词从 HashMap2 中移除
if (num > 0 && !hasRemoved) {
string firstWord = s.substr(i, wordLen);
int v = hasWords[firstWord];
hasWords[firstWord] = v - 1;
num = num - 1;
}
}
}
return res;
}
};
网友评论