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.
Example 1:
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.
Example 2:
Input:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
Output: []
题意
给定字符串s和字符串数组words,对于words中所有字符串任意顺序组合而成的字符串,如果是s的子串的求出在s中出现的所有索引。
题解
一开始暴力TLE了
1 class Solution { 2 public: 3 set<int>ans; 4 void findstr(string s,string now,deque<string>&words) { 5 if (words.empty()) { 6 int idx = s.find(now), base = 0; 7 while (idx != string::npos) { 8 ans.insert(idx+base); 9 base = base + idx + 1; 10 s=s.substr(idx + 1); 11 idx = s.find(now); 12 } 13 return; 14 } 15 int size = words.size(); 16 for (int i = 0; i < size; i++) { 17 string tmp = words[size-1]; 18 words.pop_back(); 19 findstr(s, now + tmp, words); 20 words.push_front(tmp); 21 } 22 return; 23 } 24 vector<int> findSubstring(string s, vector<string>& words) { 25 if (s == "" || words.size() == 0)return vector<int>(); 26 deque<string>wwords; 27 for (int i = 0; i < words.size(); i++) 28 wwords.push_back(words[i]); 29 findstr(s, "", wwords); 30 return vector<int>(ans.begin(),ans.end()); 31 } 32 };
后来搞了种非常混乱的方法,类似于之前有道题的滑动窗口(要看清所有单词都是相同长度的,不然是想不到这种方法的……我一开始就没看见……)
具体就是:
单词长度:l,s长度:sl
每次选定一个值为0~l-1的起始指针,初始尾指针与头指针重合,然后每次判断目前指向的那个单词(指针处于这个单词的头部)如果加进目前头尾指针形成的字符串中是否合法,如果合法就把尾指针后移l,否则把头指针移到尾指针后面。
滑动窗口还算是蛮有趣蛮有用的一个思想吧
1 class Solution { 2 public: 3 vector<int>contained, cnt, id; 4 map<string, int>idx; 5 int l; 6 vector<int> findSubstring(string s, vector<string>& words) { 7 if (s == "" || words.size() == 0)return vector<int>(); 8 vector<int>ans; 9 contained.resize(words.size()); 10 cnt.resize(words.size()); 11 id.resize(s.length()); 12 sort(words.begin(), words.end()); 13 for (int i = 0; i < contained.size(); i++) { 14 contained[i] = 0; 15 cnt[i] = 0; 16 idx.insert(make_pair(words[i], i)); 17 cnt[idx[words[i]]]++; 18 } 19 int leng = s.length(); 20 l = words[0].size(); 21 for (int i = 0; i < leng; i++) { 22 if (idx.find(s.substr(i, l)) != idx.end()) 23 id[i] = idx[s.substr(i, l)]; 24 else id[i] = -1; 25 } 26 for (int i = 0; i < l; i++) { 27 int S = i; 28 for (int j = i; j < leng; j += l) { 29 int now = id[j]; 30 if (now == -1) { 31 while (S < j) { 32 contained[id[S]]--; 33 S += l; 34 } 35 S += l; 36 continue; 37 } 38 while (contained[now] >= cnt[now]) { 39 contained[id[S]]--; 40 S += l; 41 } 42 contained[now]++; 43 if (j - S + l == l * words.size()) 44 ans.push_back(S); 45 } 46 for (int j = 0; j < contained.size(); j++) 47 contained[j] = 0; 48 } 49 return ans; 50 } 51 };