30. Substring with Concatenation of All Words
题目
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).
解决该问题的关键是理解清楚要求。
给定一个目标字符串s,一个单词集合words。
要求使得words集合中所有元素连续出现在s中的首位置组成的集合(元素顺序不考虑)。
正如所给实例,目标字符串s: “barfoothefoobarman”
对比单词集合words: [“foo”, “bar”]
我们发现,在pos=0 ~ 5时“barfoo”恰好匹配,则0压入结果vector;
在pos=9 ~ 14时“foobar”恰好匹配,则9压入结果vector;
在理清楚题意后,便可入手程序实现。
解析
- 思路:主要运用两个map,先用字典将单词存储一遍,去掉重复元素;然后依次遍历字符串,对每一个位置,查看后面的word是否在原字典中,且word个数不能超过原map的个数
1.子字符串包含且仅包含L中所有的单词,顺序无要求。
注意的是:
1.L中单词有可能重复
2.注意"aaa",{"a","a"}的结果是{0,1}的情况,就是每次直往后移动一个字符。
// 30. Substring with Concatenation of All Words
class Solution_30 {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> vec;
int words_num = words.size();
int words_len = words[0].size();
if (s.size()==0||words.size()==0||s.size()<words_num*words_len)
{
return vec;
}
unordered_map<string, int> mp;
for (string str:words)
{
mp[str]++; //去掉重复元素的words
}
for (int i = 0; i < s.size() - words_len*words_num+1;i++)
{
unordered_map<string, int> dest;
int j = 0;
for (; j < words_num;j++)
{
string temp = s.substr(i + j*words_len, words_len);
dest[temp]++;
if (!mp.count(temp)||(mp.count(temp)&&dest[temp]>mp[temp]))
{
break;
}
}
if (j==words_num)
{
vec.push_back(i);
}
}
return vec;
}
};
题目来源