LeetCode 30. Substring with Concatenation of All Words
题目
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.
For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
分析
本题是要你找出字符串s中仅包含words中元素的子串,并返回其索引。思路不难想,但要注意一个小细节:words中可能会有多个相同的字符串。
大致思路如下:
map1记录words中单词和出现的次数,并按长度分类,把长度放入vector1
从索引0开始到s.size()-1搜索从该索引开始,长度在vector1内的单词是否在map1中出现过,未出现则索引+1,清空记录了当前出现过单词的次数的map2;若出现过再比较其在map2上出现次数是否超出,未超出则在map2相应项+1;
统计允许记载的单词数量是否和words.size()相当,若相等则记录下当前的索引。
具体代码
class Solution {
struct Word {
int num;
string value;
bool operator<(const Word &a) const
{
return value < a.value;
}
Word(string str,int n):value(str),num(n){}
Word(string str):value(str),num(1){}
};
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> keys = vector<int>();
map<int, set<Word>> books = map<int, set<Word>>();
for (string word : words) {
if (books.find(word.length()) == books.end()) {
books[word.length()] = set<Word>();
keys.push_back(word.length());
books[word.length()].insert(Word(word));
}
else {
set<Word>::iterator it = books[word.length()].find(Word(word));
if (it == books[word.length()].end())
books[word.length()].insert(Word(word));
else {
int num = (*it).num + 1;
books[word.length()].erase(it);
books[word.length()].insert(Word(word, num));
}
}
}
int count = 0;
vector<int> result = vector<int>();
map<string, int> scale = map<string, int>();
int indexFront = 0;
for (int index = 0; index < s.size(); index++) {
bool mod = true;
for (int len : keys) {
if (len + index > s.size())continue;
set<Word>::iterator it = books[len].find(Word(s.substr(index, len)));
if (it == books[len].end())continue;
else {
if (scale.find(s.substr(index, len)) != scale.end()) {
if (scale[s.substr(index, len)] < (*it).num){
scale[s.substr(index, len)] = scale[s.substr(index, len)] + 1;
count++;
index = index + len - 1;
mod = false;
}
}
else {
scale[(s.substr(index, len))] = 1;
index = index + len - 1;
mod = false;
}
break;
}
}
if (mod) {
count = 0;
scale.clear();
index = indexFront;
indexFront++;
}
else if (scale.size() + count == words.size()) {
count = 0;
result.push_back(indexFront);
scale.clear();
index = indexFront;
indexFront++;
}
}
return result;
}
};
事实上还可以采用定长(每个子串的长度为确定的)匹配的方式优化,map也可以换用HashMap(unordered_map)。