【LeetCode】30. Substring with Concatenation of All Words
Substring with Concatenation of All Words
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
由于在vector中查找的复杂度是线性的,因此使用unordered_map存储L中所有单词,加快查找。
记每个单词word长度为len,字典L共有num个单词。
逐位扫描,以[0,n-len*num]分别作为起始点,判断后续的长度为len的num个word是否存在dict中,并且仅找到一次。
注意:
(1)判断某个元素word是否在map中,可以判断m[word]是否为0(int 的默认值)
(2)S.size()必须由unsigned int转为int型,若不然,当S长度较短时,减法结果会溢出。
i <= (int)S.size()-num*len
class Solution { public: vector<int> findSubstring(string S, vector<string> &L) { vector<int> ret; int num = L.size(); if(num < 1) return ret; int len = L[0].size(); //save words into map to accelerate unordered_map<string, int> dict; for(int i = 0; i < num; i ++) { dict[L[i]] ++; } //attention: if no convertion to int, S.size()-num*len will overflow for(int i = 0; i <= (int)S.size()-num*len; i ++) {//start from i unordered_map<string, int> set; int j = 0; for(; j < num; j ++) {//search [S[i+j*len], S[i+(j+1)*len]) string word = S.substr(i+j*len, len); if(dict[word] != 0 && set[word] < dict[word]) {//in dict but not in set set[word] ++; } else break; } if(j == num) {//all words found once ret.push_back(i); } } return ret; } };