给定一个字符串 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"]
输出:[]
示例 3:
输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
提示:
1 <= s.length <= 104
s 由小写英文字母组成
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i] 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<vector<string>> wordsArr;
vector<string> wordArr{words[0]};
wordsArr.insert(wordsArr.end(), wordArr);
for(int i = 1; i < words.size(); i++)
{
string word = words[i];
for(int j = 0; j < wordsArr.size(); j++)
{
wordArr = wordsArr[j];
for(int k = 0; k < wordArr.size(); k++)
{
vector<string> wordArrItem = wordArr;
wordArrItem.insert(wordArrItem.begin() + k, word);
if(k == 0)
{
wordsArr[j] = wordArrItem;
}
else
{
wordsArr.insert(wordsArr.begin() + j, wordArrItem);
j++;
}
}
wordArr.push_back(word);
wordsArr.insert(wordsArr.begin() + j, wordArr);
j++;
}
}
vector<string> composedWordsArr;
string composedString;
vector<int> result;
for(int i = 0; i < wordsArr.size(); i++)
{
for(int j = 0; j < wordsArr[i].size(); j++)
{
composedString = composedString + wordsArr[i].at(j);
}
bool repeated_flag = false;
for(int k = 0; k < composedWordsArr.size(); k++)
{
if(composedWordsArr[k] == composedString)
{
repeated_flag = true;
break;
}
}
if(!repeated_flag)
{
composedWordsArr.push_back(composedString);
vector<int> value = strStr(s, composedString);
result.insert(result.end(), value.begin(), value.end());
}
composedString = "";
}
return result;
}
private:
vector<int> strStr(string haystack, string needle) {
int needle_size = needle.size();
vector<int> result;
if(needle_size == 0)
return result;
int haystack_size = haystack.size();
if(haystack_size < needle_size)
return result;
for(int i = 0; i <= haystack_size - needle_size; i++)
{
string haystack_sub = haystack.substr(i, needle_size);
if(haystack_sub == needle)
result.push_back(i);
}
return result;
}
};
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution {
struct strWordCounter
{
string word;
int counter;
};
struct strWordsCounter
{
string word;
vector<strWordCounter> counters;
};
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<string> wordArr;
vector<strWordsCounter> wordsCounter;
vector<strWordCounter> wordCounter;
vector<int> result;
for (int i = 0; i < words.size(); i++)
{
bool isFind = false;
for (int j = 0; j < wordCounter.size(); j++)
{
if (wordCounter[j].word == words[i])
{
isFind = true;
wordCounter[j].counter++;
break;
}
}
if (!isFind)
{
strWordCounter tempCounter{words[i], 1};
wordCounter.push_back(tempCounter);
}
}
#if 1
for (int i = 0; i < wordCounter.size(); i++)
{
cout << "wordCounter[" << i << "] word = " << wordCounter.at(i).word.c_str() << " counter = " << wordCounter.at(i).counter << endl;
}
#endif
vector<strWordCounter> tempWordCounter = wordCounter;
for (int i = 0; i < wordCounter.size(); i++)
{
//cout << "wordCounter[" << i << "] word = " << wordCounter.at(i).word.c_str() << " counter = " << wordCounter.at(i).counter << endl;
if (wordCounter[i].counter <= 1)
{
tempWordCounter.erase(tempWordCounter.begin() + i);
}
else
{
tempWordCounter[i].counter--;
}
wordsCounter.push_back({ wordCounter[i].word, tempWordCounter});
tempWordCounter = wordCounter;
}
# if 1
for (int i = 0; i < wordsCounter.size(); i++)
{
cout << "wordsCounter[" << i << "] word = " << wordsCounter.at(i).word.c_str() << endl;
for (int j = 0; j < wordsCounter[i].counters.size(); j++)
{
cout << "wordCounter[" << i << "].counters[" << j << "] word = " << wordsCounter[i].counters.at(j).word.c_str() << " counter = " << wordsCounter[i].counters.at(j).counter << endl;
}
}
#endif
for (int i = 0; i < wordsCounter.size(); )
{
string tempWord = wordsCounter[i].word;
wordCounter = wordsCounter[i].counters;
wordsCounter.erase(wordsCounter.begin() + i);
#if 1
cout << "i = " << i << " tempWord = " << tempWord.c_str() << endl;
for (int j = 0; j < wordCounter.size(); j++)
{
cout << "wordCounter[" << j << "] word = " << wordCounter.at(j).word.c_str() << " counter = " << wordCounter.at(j).counter << endl;
}
#endif
if (wordCounter.empty())
{
wordArr.push_back(tempWord);
//cout << "tempWord = " << tempWord.c_str() << endl;
continue;
}
tempWordCounter = wordCounter;
for (int j = 0; j < wordCounter.size(); j++)
{
string temString = tempWord + wordCounter[j].word;
//cout << "j = " << j << " temString = " << temString.c_str() << endl;
if (wordCounter[j].counter <= 1)
{
tempWordCounter.erase(tempWordCounter.begin() + j);
//cout << "tempWordCounter erase at" << j << endl;
}
else
{
tempWordCounter[j].counter--;
//cout << "tempWordCounter at " << j << " counter = " << tempWordCounter[j].counter << endl;
}
wordsCounter.push_back({ temString, tempWordCounter });
tempWordCounter = wordCounter;
}
}
for (int i = 0; i < wordArr.size(); i++)
{
cout << "wordArr[" << i << "] = " << wordArr.at(i).c_str() << endl;
vector<int> value = strStr(s, wordArr.at(i));
result.insert(result.end(), value.begin(), value.end());
}
return result;
}
private:
vector<int> strStr(string haystack, string needle) {
int needle_size = needle.size();
vector<int> result;
if (needle_size == 0)
return result;
int haystack_size = haystack.size();
if (haystack_size < needle_size)
return result;
for (int i = 0; i <= haystack_size - needle_size; i++)
{
string haystack_sub = haystack.substr(i, needle_size);
if (haystack_sub == needle)
result.push_back(i);
}
return result;
}
};
int main()
{
Solution obj;
vector<string> words{ "dhvf","sind","ffsl","yekr","zwzq","kpeo","cila","tfty","modg","ztjg","ybty","heqg","cpwo","gdcj","lnle","sefg","vimw","bxcb" };
vector<int> result = obj.findSubstring("pjzkrkevzztxductzzxmxsvwjkxpvukmfjywwetvfnujhweiybwvvsrfequzkhossmootkmyxgjgfordrpapjuunmqnxxdrqrfgkrsjqbszgiqlcfnrpjlcwdrvbumtotzylshdvccdmsqoadfrpsvnwpizlwszrtyclhgilklydbmfhuywotjmktnwrfvizvnmfvvqfiokkdprznnnjycttprkxpuykhmpchiksyucbmtabiqkisgbhxngmhezrrqvayfsxauampdpxtafniiwfvdufhtwajrbkxtjzqjnfocdhekumttuqwovfjrgulhekcpjszyynadxhnttgmnxkduqmmyhzfnjhducesctufqbumxbamalqudeibljgbspeotkgvddcwgxidaiqcvgwykhbysjzlzfbupkqunuqtraxrlptivshhbihtsigtpipguhbhctcvubnhqipncyxfjebdnjyetnlnvmuxhzsdahkrscewabejifmxombiamxvauuitoltyymsarqcuuoezcbqpdaprxmsrickwpgwpsoplhugbikbkotzrtqkscekkgwjycfnvwfgdzogjzjvpcvixnsqsxacfwndzvrwrycwxrcismdhqapoojegggkocyrdtkzmiekhxoppctytvphjynrhtcvxcobxbcjjivtfjiwmduhzjokkbctweqtigwfhzorjlkpuuliaipbtfldinyetoybvugevwvhhhweejogrghllsouipabfafcxnhukcbtmxzshoyyufjhzadhrelweszbfgwpkzlwxkogyogutscvuhcllphshivnoteztpxsaoaacgxyaztuixhunrowzljqfqrahosheukhahhbiaxqzfmmwcjxountkevsvpbzjnilwpoermxrtlfroqoclexxisrdhvfsindffslyekrzwzqkpeocilatftymodgztjgybtyheqgcpwogdcjlnlesefgvimwbxcbzvaibspdjnrpqtyeilkcspknyylbwndvkffmzuriilxagyerjptbgeqgebiaqnvdubrtxibhvakcyotkfonmseszhczapxdlauexehhaireihxsplgdgmxfvaevrbadbwjbdrkfbbjjkgcztkcbwagtcnrtqryuqixtzhaakjlurnumzyovawrcjiwabuwretmdamfkxrgqgcdgbrdbnugzecbgyxxdqmisaqcyjkqrntxqmdrczxbebemcblftxplafnyoxqimkhcykwamvdsxjezkpgdpvopddptdfbprjustquhlazkjfluxrzopqdstulybnqvyknrchbphcarknnhhovweaqawdyxsqsqahkepluypwrzjegqtdoxfgzdkydeoxvrfhxusrujnmjzqrrlxglcmkiykldbiasnhrjbjekystzilrwkzhontwmehrfsrzfaqrbbxncphbzuuxeteshyrveamjsfiaharkcqxefghgceeixkdgkuboupxnwhnfigpkwnqdvzlydpidcljmflbccarbiegsmweklwngvygbqpescpeichmfidgsjmkvkofvkuehsmkkbocgejoiqcnafvuokelwuqsgkyoekaroptuvekfvmtxtqshcwsztkrzwrpabqrrhnlerxjojemcxel", words);
for (int i = 0; i < result.size(); i++)
{
cout << result[i] << " ";
}
cout << endl;
return 0;
}
现在处理时间还是太长,需要继续改进。在处理过程中,如果一个string不能找到,就直接删除。
class Solution {
struct strWordCounter
{
string word;
int counter;
};
struct strWordsCounter
{
string word;
vector<strWordCounter> counters;
};
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<string> wordArr;
vector<strWordsCounter> wordsCounter;
vector<strWordCounter> wordCounter;
vector<int> result;
int wordSize = 0;
for (int i = 0; i < words.size(); i++)
{
bool isFind = false;
wordSize += words[i].size();
for (int j = 0; j < wordCounter.size(); j++)
{
if (wordCounter[j].word == words[i])
{
isFind = true;
wordCounter[j].counter++;
break;
}
}
if (!isFind)
{
strWordCounter tempCounter{words[i], 1};
wordCounter.push_back(tempCounter);
}
}
for (int i = 0; i < wordCounter.size(); i++)
{
if (!strHasEnoughWordCounter(s, wordCounter.at(i).word, wordCounter.at(i).counter, 0))
{
return result;
}
}
vector<strWordCounter> tempWordCounter = wordCounter;
for (int i = 0; i < wordCounter.size(); i++)
{
if (wordCounter[i].counter <= 1)
{
tempWordCounter.erase(tempWordCounter.begin() + i);
}
else
{
tempWordCounter[i].counter--;
}
wordsCounter.push_back({ wordCounter[i].word, tempWordCounter});
tempWordCounter = wordCounter;
}
for (int i = 0; i < wordsCounter.size(); )
{
string tempWord = wordsCounter[i].word;
wordCounter = wordsCounter[i].counters;
wordsCounter.erase(wordsCounter.begin() + i);
if (wordCounter.empty())
{
wordArr.push_back(tempWord);
continue;
}
tempWordCounter = wordCounter;
for (int j = 0; j < wordCounter.size(); j++)
{
string temString = tempWord + wordCounter[j].word;
if (strHasEnoughWordCounter(s, temString, 1, wordSize - temString.size()))
{
if (wordCounter[j].counter <= 1)
{
tempWordCounter.erase(tempWordCounter.begin() + j);
}
else
{
tempWordCounter[j].counter--;
}
wordsCounter.push_back({ temString, tempWordCounter });
tempWordCounter = wordCounter;
}
}
}
for (int i = 0; i < wordArr.size(); i++)
{
vector<int> value = strStr(s, wordArr.at(i), 0);
result.insert(result.end(), value.begin(), value.end());
}
return result;
}
private:
bool strHasEnoughWordCounter(string haystack, string needle, int counter, int offset) {
int needle_size = needle.size();
int tmpCounter = 0;
if (needle_size == 0)
return true;
int haystack_size = haystack.size();
if (haystack_size < needle_size)
return false;
for (int i = 0; i <= haystack_size - needle_size - offset; i++)
{
string haystack_sub = haystack.substr(i, needle_size);
if (haystack_sub == needle)
tmpCounter++;
if (tmpCounter >= counter)
return true;
}
return false;
}
vector<int> strStr(string haystack, string needle, int offset) {
int needle_size = needle.size();
vector<int> result;
if (needle_size == 0)
return result;
int haystack_size = haystack.size();
if (haystack_size < needle_size)
return result;
for (int i = 0; i <= haystack_size - needle_size - offset; i++)
{
string haystack_sub = haystack.substr(i, needle_size);
if (haystack_sub == needle)
result.push_back(i);
}
return result;
}
};
#include <map>
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> result;
int wordSize = 0;
int sSize = s.size();
map<char, int> wordsCharTable; // 记录words a~z的数目
map<char, int> sCharTable; // 记录当前i位置处子字符串 a~z的数目
vector<string> correctStringVec; // 记录字母数目相同,正确的String
vector<string> wronStringVec; // 记录字母数目相同,错误的String
for (char i = 'a'; i <= 'z'; i++)
{
wordsCharTable[i] = 0;
sCharTable[i] = 0;
}
for (int i = 0; i < words.size(); i++)
{
wordSize += words[i].size();
for (int j = 0; j < words[i].size(); j++)
{
wordsCharTable[words[i][j]]++;
}
}
int sWordLen = sSize - wordSize;
if (sWordLen < 0)
{
return result;
}
for (int i = 0; i < wordSize; i++)
{
sCharTable[s[i]]++;
}
for (int i = 0; i <= sWordLen; i++)
{
// 尽量在第一个for循环下面多做判断
if (i != 0)
{
sCharTable[s[i - 1]]--;
sCharTable[s[i + wordSize - 1]]++;
}
if (wordsCharTable != sCharTable)
{
continue;
}
else
{
string wholeContxt = s.substr(i, wordSize);
bool inCcorrectStringVec = false;
for (auto const& strObj : correctStringVec)
{
if (strObj == wholeContxt)
{
inCcorrectStringVec = true;
break;
}
}
if (inCcorrectStringVec)
{
result.push_back(i);
continue;
}
else
{
bool inWronStringVec = false;
for (auto const& strObj : wronStringVec)
{
if (strObj == wholeContxt)
{
inWronStringVec = true;
break;
}
}
if (inWronStringVec)
{
continue;
}
}
}
vector<string> tmpWords = words;
for (int j = i; j < i + wordSize; )
{
bool isFind = false;
for (int k = 0; k < tmpWords.size(); k++)
{
string s_sub = s.substr(j, tmpWords[k].size());
if (s_sub == tmpWords[k])
{
j += s_sub.size();
tmpWords.erase(tmpWords.begin() + k);
isFind = true;
break;
}
}
if (!isFind)
{
break;
}
}
if (tmpWords.empty())
{
result.push_back(i);
correctStringVec.push_back(s.substr(i, wordSize));
}
else
{
wronStringVec.push_back(s.substr(i, wordSize));
}
}
return result;
}
};