给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:
s = "barfoothefoobarman",
words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
输出:[]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
//map 和滑动窗口 class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { if(!s.length()||!words.size())return {}; int one_size=words[0].length();//一个单词的大小 int words_size=words.size();//一共又多少个单词 int size=one_size*words_size;//需要在s中截取的大小 if(size>s.length())return {};// vector<int> res; unordered_map<string,int> target; for(auto str:words)target[str]++;//设置目标map for(int i=0;i<s.length()-size+1;i++) { unordered_map<string,int> cur;//当前的map for(int k=0;k<words_size;k++)//对当前s中截取的字符串 中的words_size个单词进行map统计 { string w=s.substr(i+one_size*k,one_size);//截取一个单词 if(target.find(w)==target.end())break;//若这个单词在target中没有就结束 cur[w]++;//统计当前的map } if(cur==target)res.push_back(i);//若当前的map等于target的map 将i加入到答案中 } return res; } };
//比较map是否相同 //起始位置从0->one_size //然后一次截取one_size个字符串 设置left和right class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { if(!s.length()||!words.size())return {}; int one_size=words[0].length();//一个单词的大小 int words_size=words.size();//一共又多少个单词 int size=one_size*words_size;//需要在s中截取的大小 if(size>s.length())return {}; vector<int> res; unordered_map<string,int> target; for(const auto& str:words)target[str]++;//设置目标map for(int start=0;start<one_size;start++)//设置不同的起点 { int left=start,right=start,count=0; unordered_map<string,int> cur;//当前的map while(right+one_size<=s.length()) { string w=s.substr(right,one_size);//截取一个单词 right+=one_size;//移动右边界 if(target.find(w)==target.end())//若当前单词不在target中 则重置 { count=0; cur.clear(); left=right; } else { cur[w]++; count++; //为什么是while呢 //因为左边第一个单词不一定是w while(target[w]<cur[w])//若当前w的次数大于target中w的次数 则左移 { string str=s.substr(left,one_size); cur[str]--; left+=one_size; count--; } if(count==words_size)res.push_back(left); } } } return res; } };