问题介绍
问题描述:
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.
示例:
Input:S = “barfoothefoobarman”,words = [“foo”,“bar”]; Output:[0,9] Explanation:Substrings starting at index 0 and 9 are “barfoor” and “foobar” respectively.The output order does not matter, returning [9,0] is fine too.
约束条件:NULL
解决思路
思路:
分析题目后,可以想到题目可以分解为两部分:1.字符串的子串匹配;2.子串的拼接;可以想到的暴力解决方法为,将words中所有的单词存在的组合拼接出来,然后作为子串,挨个与带匹配字符串S进行匹配,虽然可行,但是时间复杂度过高; 对于子串的拼接,可以维护一个包含所有words的vector dic,每当成功匹配一个dic中的字符串就将dic中对应的那个字符串删除,若是匹配dic中包含的所有子串都匹配失败,则表示字符串S的当前位置不是我们所要求的,则将dic恢复为初始化words; 对于每一个dic中的子串,将当前S字符串遍历到的位置i保存下来,进行匹配,当dic中的子串全部遍历后,如果dic没有为空,则表示S字符串当前的位置不满足要求,进行i++的操作,否表示i为我们需要求的S字符串的位置,将i存入vector resp结果中;对于S字符串的遍历不需要遍历全部长度,因为最后需要预留一个words中所有子串的长度和,所以遍历的实际长度为:s.length()-(lxwords.size())+1即可;
问题: 该算法的时间复杂度为O(s.length()xwords.size()xwords[0].length()),在LeetCode提交结果显示并不太好,属于刚刚能通过时间复杂度检验的水平,还有待改进;
代码 :
class Solution {
public:
vector< int > findSubstring ( string s, vector< string> & words) {
vector< int > resp;
vector< int > pos;
vector< string> dic;
int sign= - 1 ;
int l;
if ( words. empty ( ) )
{
return resp;
}
else
{
l= words[ 0 ] . length ( ) ;
dic. assign ( words. begin ( ) , words. end ( ) ) ;
}
if ( s. empty ( ) )
{
return resp;
}
else
{
int count= s. length ( ) - ( l* words. size ( ) ) + 1 ;
for ( int i= 0 ; i< count; i++ )
{
int x= i;
int j= 0 ;
while ( j< dic. size ( ) )
{
int z= 0 ;
while ( z< dic[ j] . length ( ) && s[ x+ z] == dic[ j] [ z] )
{
z++ ;
}
if ( z== dic[ j] . length ( ) )
{
dic. erase ( dic. begin ( ) + j) ;
x+ = l;
j= 0 ;
}
else
{
j++ ;
}
}
if ( dic. empty ( ) )
{
resp. push_back ( i) ;
}
dic. clear ( ) ;
dic. assign ( words. begin ( ) , words. end ( ) ) ;
}
return resp;
}
}
} ;