/*
30. Substring with Concatenation of All Words My Submissions QuestionEditorial Solution
Total Accepted: 53094 Total Submissions: 255639 Difficulty: Hard
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).
Subscribe to see which companies asked this question
*/
/*
解题思路:
1.逐一单词遍历。若发现有一个单词存在集合中,则截取以此单词为开头以所有单词总长度为长度的字符串进行判断。
2.判断字符串中是否含有了集合中的所有单词,将截取的字符串分割成等长的子串集合,排序。最后与给定的字符串集合进行比较即可
*/
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> res;
sort(words.begin(),words.end());
int n=s.size(),m=words.size(),mm=words[0].size();
for(int i=0;i<n-m*mm+1;i++){
if(find(words.begin(),words.end(),s.substr(i,mm))!=words.end() && isvalid(words,s.substr(i,m*mm))){
res.push_back(i);
}
}
return res;
}
bool isvalid(vector<string> words,string s){
int n=words[0].size();
vector<string> tmp;
for(int i=0;i<s.size();i+=n){
string t=s.substr(i,n);
tmp.push_back(t);
}
sort(tmp.begin(),tmp.end());
return tmp==words;
}
};
/*
牛人做法:
解题思路:
这道题让我们求串联所有单词的子串,就是说给定一个长字符串,再给定几个长度相同的单词,让我们找出串联给定所有单词的子串的起始位置,还是蛮有难度的一道题。这道题我们需要用到两个哈希表,第一个哈希表先把所有的单词存进去,然后从开头开始一个个遍历,停止条件为当剩余字符个数小于单词集里所有字符的长度。这时候我们需要定义第二个哈希表,然后每次找出给定单词长度的子串,看其是否在第一个哈希表里,如果没有,则break,如果有,则加入第二个哈希表,但相同的词只能出现一次,如果多了,也break。如果正好匹配完给定单词集里所有的单词,则把i存入结果中,具体参见代码如
*/
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> res;
if (s.empty() || words.empty()) return res;
int n = words.size(), m = words[0].size();
unordered_map<string, int> m1;
for (auto &a : words) ++m1[a];
for (int i = 0; i <= (int)s.size() - n * m; ++i) {
unordered_map<string, int> m2;
int j = 0;
for (j = 0; j < n; ++j) {
string t = s.substr(i + j * m, m);
if (m1.find(t) == m1.end()) break;
++m2[t];
if (m2[t] > m1[t]) break;
}
if (j == n) res.push_back(i);
}
return res;
}
};