792. Number of Matching Subsequences
Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S.
Example :
Input:
S = “abcde”
words = [“a”, “bb”, “acd”, “ace”]
Output: 3
Explanation: There are three words in words that are a subsequence of S: “a”, “acd”, “ace”.
Note:
- All words in words and S will only consists of lowercase letters.
- The length of S will be in the range of [1, 50000].
- The length of words will be in the range of [1, 5000].
- The length of words[i] will be in the range of [1, 50].
方法1:
思路:
brute force的方法最高50 * 5000 * 50000的复杂度,需要优化。string s的位置信息被重复使用,只需要hash所有char的index就可以。每次查找时记录上一个字母找到的位置prev,下一个位置不能低于prev。这里用binary search的内置函数upper_bound找到第一个大于prev + 1的index,如果没找到,可以直接break。
这里运用到了找subsequence的经典子函数。
Complexity
Time complexity: O(S + W * L * log(S))
Space complexity: O(S)
S: length of S
W: number of words
L: length of a word
class Solution {
public:
int numMatchingSubseq(string S, vector<string>& words) {
unordered_map<char, vector<int>> hash;
int res = 0;
for (int i = 0; i < S.size(); i++) hash[S[i]].push_back(i);
for (string word: words) {
int prev = -1, i = 0;
for (; i < word.size(); i++) {
if (!hash.count(word[i])) break;
auto it = upper_bound(hash[word[i]].begin(), hash[word[i]].end(), prev);
if (it == hash[word[i]].end()) break;
prev = *it;
}
if (i == word.size()) res++;
}
return res;
}
};