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).
知识补充:
unordered_map
unordered_map<int, int> c;//<type,type>分别对应键的类型和键值的类型
c[0] = 1;//简单的插入数据形式
c.find(key)==c.end();//判断无序图内是否有这个键
c.count(key);//访问键值
测试代码:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> result;
unordered_map<string, int> c;
unordered_map<string, int> n;
int j,i,k;
string ss;
int l = words[0].length();
for (string word : words)
c[word]++;
for(i=0;i<s.length()-l*words.size()+1;i++)
{
j=i;
k=words.size();
n = c;
while(k)
{
ss = s.substr(j,l);
if(n[ss]<1)
{
break;
}
if(n.find(ss)!=n.end())
{
--n[ss];
j = j+l;
k--;
}else{
break;
}
}
if(k==0)
{
result.push_back(i);
}
}
return result;
}
性能:
参考答案:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;
if(words.empty() || words[0].length()==0) return ret;
int wl=words[0].length();
int len=wl*words.size();
int end=s.length()-len;
if(end<0) return ret;
unordered_map<string, int> dict;
for(string word : words) dict[word]++;
for(int st=0; st<wl; st++) {
helper(ret, dict, s, words, st, end, wl, len);
}
return ret;
}
private:
void helper(vector<int>& ret, unordered_map<string, int>& dict, string& s, vector<string>& words, int st, int end, int wl, int len) {
unordered_map<string, int> hash;
int left=st, right=st;
while(left<=end) {
string nxt=s.substr(right, wl);
if(dict.count(nxt)==0) {
left=right+wl;
hash.clear();
}
else {
if(hash.count(nxt)==0) hash[nxt]=1;
else if(hash[nxt]<dict[nxt]) hash[nxt]++;
else {
string rem=s.substr(left, wl);
while(rem!=nxt) {
hash[rem]--;
left+=wl;
rem=s.substr(left, wl);
}
left+=wl;
}
}
right+=wl;
if(right-left==len) ret.push_back(left);
}
}
};