1+ class Solution {
2+ // Runtime: 20 ms, faster than 98.91% of C++ online submissions for Substring with Concatenation of All Words.
3+ // Memory Usage: 10.8 MB, less than 99.11% of C++ online submissions for Substring with Concatenation of All Words.
4+ public:
5+ vector<int > findSubstring (string SS, vector<string> &L) {
6+ vector<int > ans;
7+ if (SS.size () == 0 || L.size () == 0 )
8+ return ans;
9+ string_view S=SS;
10+ unordered_map<string_view, int > dict;
11+ for (const auto &s:L)
12+ ++dict[s];
13+ const int wl = L[0 ].size ();
14+ const int totalLength = L.size () * wl;
15+ auto slideLeftWindow = [wl](auto & tdict,auto & S,auto & left,auto &count){
16+ --tdict[S.substr (left, wl)];
17+ --count;
18+ left += wl;
19+ };
20+ for (int i = 0 ; i < wl; ++i) {
21+ int left = i, count = 0 ;
22+ unordered_map<string_view, int > tdict;
23+ for (int j = i; left + totalLength <= S.size (); j += wl)
24+ if (auto str = S.substr (j, wl);dict.count (str)) {
25+ ++tdict[str];
26+ ++count;
27+ if (tdict[str] <= dict[str] && count == L.size ()) {
28+ ans.push_back (left);
29+ slideLeftWindow (tdict,S,left,count);
30+ }
31+ else while (tdict[str] > dict[str])
32+ slideLeftWindow (tdict,S,left,count);
33+ }
34+ else {
35+ tdict.clear ();
36+ count = 0 ;
37+ left = j + wl;
38+ }
39+ }
40+ return ans;
41+ }
42+ };
0 commit comments