30. Substring with Concatenation of All Words
Problem's Link
----------------------------------------------------------------------------
Mean:
给你一个字符串s,和一个字符串集合words,找出s中words所有单词连续出现的起始下标.
analyse:
思路:窗口滑动算法.
枚举所有长度为words[0].length()的子串,然后使用窗口滑动算法来统计.
Trick:集合words是一个可重集,当连续出现的单词书大于words中的时,需要回退删除开头部分的单词,注意细节.
Time complexity: O(N)
view code
class
Solution
{
public :
vector < int > findSubstring( string s , vector < string > & words)
{
vector < int > ans;
int n = s . size (), cnt = words . size();
if (n <= 0 || cnt <= 0) return ans;
// init word occurence
unordered_map < string , int > dict;
for ( int i = 0; i < cnt; ++ i) //统计每个单词出现的次数
dict [ words [ i ]] ++;
// travel all sub string combinations
int wl = words [ 0 ]. size();
for ( int i = 0; i < wl; ++ i)
{
int left = i , continueWords = 0;
unordered_map < string , int > tdict;
for ( int j = i; j <= n - wl; j += wl)
{
string str = s . substr( j , wl);
// a valid word, accumulate results
if ( dict . count( str))
{
tdict [ str ] ++;
if ( tdict [ str ] <= dict [ str ])
continueWords ++;
else
{
// a more word, advance the window left side possiablly
while ( tdict [ str ] > dict [ str ])
{
string str1 = s . substr( left , wl);
tdict [ str1 ] --;
if ( tdict [ str1 ] < dict [ str1 ]) continueWords --;
left += wl;
}
}
// come to a result
if ( continueWords == cnt)
{
ans . push_back( left);
// advance one word
tdict [s . substr( left , wl )] --;
continueWords --;
left += wl;
}
}
// not a valid word, reset all vars
else
{
tdict . clear();
continueWords = 0;
left = j + wl;
}
}
}
return ans;
}
};
{
public :
vector < int > findSubstring( string s , vector < string > & words)
{
vector < int > ans;
int n = s . size (), cnt = words . size();
if (n <= 0 || cnt <= 0) return ans;
// init word occurence
unordered_map < string , int > dict;
for ( int i = 0; i < cnt; ++ i) //统计每个单词出现的次数
dict [ words [ i ]] ++;
// travel all sub string combinations
int wl = words [ 0 ]. size();
for ( int i = 0; i < wl; ++ i)
{
int left = i , continueWords = 0;
unordered_map < string , int > tdict;
for ( int j = i; j <= n - wl; j += wl)
{
string str = s . substr( j , wl);
// a valid word, accumulate results
if ( dict . count( str))
{
tdict [ str ] ++;
if ( tdict [ str ] <= dict [ str ])
continueWords ++;
else
{
// a more word, advance the window left side possiablly
while ( tdict [ str ] > dict [ str ])
{
string str1 = s . substr( left , wl);
tdict [ str1 ] --;
if ( tdict [ str1 ] < dict [ str1 ]) continueWords --;
left += wl;
}
}
// come to a result
if ( continueWords == cnt)
{
ans . push_back( left);
// advance one word
tdict [s . substr( left , wl )] --;
continueWords --;
left += wl;
}
}
// not a valid word, reset all vars
else
{
tdict . clear();
continueWords = 0;
left = j + wl;
}
}
}
return ans;
}
};