前言:这道题我做得有点崩溃,前前后后做了很多次,一直都卡在倒数第二个测试用例没有通过,
本来是没打算发这道题的,因为没怎么通过,但想了一下,我修改代码的过程还是蛮宝贵的,所以就打算还是发出来启发一下你怎么修改代码,所以,这道题没什么参考价值,我就随便写写咯
解题思路:
1.获取信息:
(1)给定一个字符串和字符串数组,要求按任意顺序组合字符串数组中所有的字符串
再检验组合成的字符串是否是给定的那个字符串的子串
如果是,就记录下子串的首字符在给定字符串的下标
(2)它给了例子,可以结合例子理解一下
(3)那些首字符的下标们可以按任意顺序返回哦
2.分析题目:
这道题让我想到了力扣第28题,这道题的匹配字符串环节大概就是第28题,第28题我使用了两种方法,一种是滑动窗口法来匹配,一种是KMP算法
这道题我就选用滑动窗口法来进行这一步骤,一方面是简化这道题,让它比较好理解,一方面是给自己上上强度
这样我们就将这道题拆分成了两个小问题了,其中一个小问题,匹配子串,我们已经知道怎么解决了,另一个小问题,就是该怎么获得字符串数组中字符串组合后形成的字符串了
具体获取方法,我会放在下面的方法结合代码来帮助你理解
3.示例查验:
示例1,示例2和示例3:你可以结合示例看一下自己获取的信息是否正确,是否有遗漏
4.尝试编写代码:
(1)递归配组合,动态规划和滑动窗口来检验(会超时)
直接看代码吧,跟28题的解法差不多,只不过多了个递归而已
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int>res;
string str;
int size=words.size();
GetRes(res,str,size,0,s,words);
return res;
}
private:
void GetRes(vector<int>&res,string str,int size,int now,string&s,vector<string>words){
if(now==size){
int begin=0,end=str.size()-1;
while(end<s.size()&&begin<=end){
if(str[0]==s[begin]&&str[str.size()-1]==s[end])rever(s,str,begin,end,res);
begin++;end++;
}
return;
}
for(int i=0;i<size;i++){
if(words[i]=="")continue;
string temp=str;
temp+=words[i];
string UH=words[i];
words[i]="";
GetRes(res,temp,size,now+1,s,words);
words[i]=UH;
}
}
void rever(string&s,string str,int begin,int end,vector<int>&res){
int head=0,tail=str.size()-1;
int UH=begin;
while(head<=tail){
if(str[head]!=s[begin]||str[tail]!=s[end])return;
begin++;end--;head++;tail--;
}
if(find(res.begin(),res.end(),UH)==res.end()){
res.push_back(UH);
}
}
};
(2)尝试打算牺牲一下空间复杂度来拯救一下时间复杂度(会超时)
如方法名字所言,就是这么个优化思路
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int>res;
vector<string>table;
string str;
int size=words.size();
GetRes(res,str,size,0,s,words,table);
int border=table.size();
int UH=s.size();
for(int i=0;i<border;i++){
int begin=0,end=table[i].size()-1;
while(end<UH&&begin<=end){
if(s[begin]==table[i][0]&&s[end]==table[i][table[i].size()-1])rever(s,table[i],begin,end,res);
begin++;end++;
}
}
return res;
}
private:
void GetRes(vector<int>&res,string str,int size,int now,string&s,vector<string>words,vector<string>&table){
if(now==size){
if(find(table.begin(),table.end(),str)==table.end())table.push_back(str);
return;
}
for(int i=0;i<size;i++){
if(words[i]=="")continue;
string temp=str;
temp+=words[i];
string UH=words[i];
words[i]="";
GetRes(res,temp,size,now+1,s,words,table);
words[i]=UH;
}
}
void rever(string&s,string str,int begin,int end,vector<int>&res){
int head=0,tail=str.size()-1;
int UH=begin;
while(head<=tail){
if(str[head]!=s[begin]||str[tail]!=s[end])return;
begin++;end--;head++;tail--;
}
res.push_back(UH);
}
};
(3)另辟蹊径法(会超时)
上面的方法,我尽可能优化过了,没办法,只好推倒重来了
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int>res;
int cap=words[0].size();
int size=words.size()*cap;
for(int i=0;i<s.size();i++){
int end=i+size-1;
if(end<s.size()&&GetRes(s,i,end,cap,words))res.push_back(i);
}
return res;
}
private:
bool GetRes(string&s,int begin,int end,int cap,vector<string>words){
while(begin<=end){
string str=s.substr(begin,cap);
int i=0;
for(i;i<words.size();i++){
if(words[i]==str){
words[i]="";
i=-1;break;
}
}
if(i!=-1)return false;
begin+=cap;
}
return true;
}
};
(4)处理了明显不是起始位置的位置(会超时)
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
unordered_map<char,bool>head;
unordered_map<string,int>hash;
vector<int>res;
for(string&word:words){
head[word[0]]=true;
hash[word]++;
}
int cap=words[0].size();
int room=cap*words.size();
int border=s.size();
for(int i=0;i<border;i++){
int end=i+room-1;
if(end<border&&head.find(s[i])!=head.end()&&Check(s,i,end,hash,cap))res.push_back(i);
}
return res;
}
private:
bool Check(string&s,int begin,int end,unordered_map<string,int> hash,int cap){
while(begin<=end){
string str=s.substr(begin,cap);
hash[str];
if(hash[str]==0)return false;
hash[str]--;
begin+=cap;
}
return true;
}
};
这是对上述方法的优化
(5)绞尽脑汁修改了一下(超时)
我尽力又再次修改了一下,但还是不过
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
unordered_map<char,bool>head;
unordered_map<string,int>hash;
vector<int>res;
for(string&word:words){
head[word[0]]=true;
hash[word]++;
}
int cap=words[0].size();
int room=cap*words.size();
int border=s.size();
if(room>border)return res;
for(int i=0;i<=border-room;i++){
if(head.find(s[i])!=head.end()&&Check(s,i,i+room-1,hash,cap))res.push_back(i);
}
return res;
}
private:
bool Check(string&s,int begin,int end,unordered_map<string,int> hash,int cap){
while(begin<=end){
string str=s.substr(begin,cap);
hash[str];
if(hash[str]==0)return false;
hash[str]--;
begin+=cap;
}
return true;
}
};
(6)推倒重来吧(已经是我认为我能写出来的最极致的方法了,但还是超时了)
重新换了个思路,发现还是不行,现阶段我应该是写不出来了,放到以后吧
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
unordered_map<char,bool>head;
vector<int>res;
int cap=words[0].size();
int room=cap*words.size();
int border=s.size();
if (room>border)return res;
for(string&word:words)head[word[0]]=true;
unordered_map<string,int>wordCount;
for(string&word:words)wordCount[word]++;
for(int i=0;i<=border-room;i++) {
if(!head.count(s[i]))continue;
unordered_map<string,int>temp;
for(int j=i;j<i+room;j+=cap){
string str=s.substr(j,cap);
if(!head.count(str[0]))break;
temp[str]++;
}
if(temp==wordCount)res.push_back(i);
}
return res;
}
};
这次的题解,看看就行了,毕竟我写的代码哪个都没通过,还是有点丢人的,你可以参考一下我这种优化,优化不行就换思路的方法和不服输的精神,坚持不懈的毅力嘛
等以后再重写这道题吧,暂时放弃了
1328

被折叠的 条评论
为什么被折叠?



