You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
一开没理解清楚题目意思,蛋疼。需要注意的是words中可以出现重复的word.
思路一:通过两个ordered_map来判断某一个字串是不是words中的所有词汇的组合。
代码如下:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
unordered_map<string,int> map;
vector<int> result;
int num = words.size();
int len = words[0].length();
if(words.size() == 0 || s.length() == 0 || num*len > s.length())
return result;
for(int i=0;i<num;i++)
map[words[i]]++;
for(int i=0;i<=s.length()-num*len;i++)
{
unordered_map<string,int> seen;
int j=0;
for(;j<num;j++)
{
string str = s.substr(i+j*len,len);
if(map.find(str) != map.end())
{
seen[str]++;
if(seen[str] > map[str])
break;
}
else
break;
}
if(j==num)
{
result.push_back(i);
}
}
return result;
}
};
思路二:通过查阅网上资料发现了一个更高小的方法,就是最小滑动窗口。因为word是固定大小的,所以设定起始位置start分别为0,1...word.length(),然后end初始于start相同,start标识窗口的左边框,end标识窗口的右边框。当符合要求,则end右移,当不符合情况时,左边框右移直至窗口内容符合要求。
代码如下:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
unordered_map<string,int> map;
vector<int> result;
int num = words.size();
int len = words[0].length();
if(words.size() == 0 || s.length() == 0 || num*len > s.length() )
return result;
for(int i=0;i<num;i++)
map[words[i]]++;
for(int i=0;i<len;i++)
{
unordered_map<string,int> newMap;
int start = i;
int count = 0;
for(int end=start;end<=s.length()-len;end+=len)
{
string str = s.substr(end,len);
if(map.find(str) == map.end())
{
start = end+len;
count = 0;
newMap.clear();
continue;
}
newMap[str]++;
count++;
while(newMap[str] > map[str])
{
string tmp = s.substr(start,len);
newMap[tmp]--;
count--;
start += len;
}
if(count == num)
{
result.push_back(start);
string tmp = s.substr(start,len);
newMap[tmp]--;
count --;
start += len;
}
}
}
return result;
}
};
思路三:还看到了大神写的ac自动机加最小滑动窗口(http://blog.csdn.net/u014664226/article/details/50963817) 留待以后实现