见注释。滑动窗口还是好用。

class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int>res;
if(words.empty()||s.empty())
return res;
map<string,int>allWords;
int wordLen=words[0].size();
int wordNum=words.size();
for(int i=0;i<wordNum;i++)
{
if(allWords.find(words[i])!=allWords.end())
allWords[words[i]]++;
else
allWords.insert(make_pair(words[i],1));
} bool hasRemoved=false;
map<string, int> hasWords;
//将所有移动分成 wordLen 类情况 即从i=0,1,2...wordLen-1处开始,每次移动WordLen长度
for (int j = 0; j < wordLen; j++) {
hasWords.clear();
int num = 0; //记录当前hasWords中有多少个单词
for (int i = j; i +wordNum * wordLen< s.length()+1; i = i + wordLen) { //每次判断一个窗口,窗口从i开始长 wordNum * wordLen 窗口每次移动一个单词长度
hasRemoved = false; //防止情况三移除后,情况一继续移除
while (num < wordNum) {
string word = s.substr(i + num * wordLen,wordLen);
if (allWords.find(word)!=allWords.end()) {
if(hasWords.find(word)!=hasWords.end())
hasWords[word]++;
else
hasWords.insert(make_pair(word,1));
//遇到了符合的单词,但是次数超了
if (hasWords[word] > allWords[word]) {
hasRemoved = true;
int removeNum = 0;
//一直移除单词,直到次数符合了
while (hasWords[word] > allWords[word]) {
string firstWord = s.substr(i + removeNum * wordLen,wordLen);
hasWords[firstWord]-=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);
hasWords[firstWord]-=1;
num = num - 1;
} } }
return res;
}
};

最新文章

  1. 一个简单oop的changeTab
  2. jquery-leonaScroll-1.2-自定义滚动条插件
  3. 【转】mysql对large page的支持
  4. Linux 命令行快捷键
  5. PHP实现RESTful风格的API实例(三)
  6. php和js一起实现倒计时功能
  7. 如何在 IIS 中设置 HTTPS 服务
  8. JS基础----&gt;js中ajax的使用
  9. UVA 12373 Pair of Touching Circles
  10. javascript遍历控件(实例详解)
  11. RapeLay(电车之狼R)的结局介绍 (隐藏结局攻略)
  12. GlusterFS最佳实践
  13. hashmap简单实例(个人使用经验)
  14. aarch64的架构:unrecognized command line option &#39;-mfpu=neon&#39;
  15. GHSpro多数据库连接
  16. verilog-产生axis数据流
  17. mysql查看变量/配置文件位置
  18. 家庭版Windows设置远程连接
  19. 从xtrabackup备份恢复单表【转】
  20. 【医疗行业】关于dcm4che DICOM Toolkit:C-Move与C-Get

热门文章

  1. Mysql简要概述
  2. kubernetes 核心技术-Controller 控制器
  3. your service shouldn’t know anything about HTTP headers, or gRPC error codes 干净架构 服务不应知道 HTTP头、gRPC错误码 服务仅知道服务相关的
  4. pywin32 pywin32 docx文档转html页面 word doc docx 提取文字 图片 html 结构
  5. tarjan 复习笔记 割点与桥
  6. 数位dp 笔记
  7. sql多行合并
  8. 最短路-Bellmm-ford算法
  9. GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换
  10. navicat连接阿里云mysql数据库服务器遇到的1130等相关问题