1024 · Number of Matching Subsequences
Algorithms
Medium
Description
Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S.
Subsequence is different from substring. Subsequences may not be continuous.
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].
Example
Example 1:
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”.
Example 2:
Input: S = “dsahjpjauf”, words = [“ahjpjau”,“ja”,“ahbwzgqnuk”,“tnmlanowax”]
Output: 2
Tags
Company
Google
Related Problems
1263
Is Subsequence
Medium
解法1:binary search
这题跟Lintcode 1263比较像。但因为这题有多个word要跟s匹配,所以可以先做预处理把s中每个字符c对应的位置存到mp[c]对应的vector里面,然后对于每个word,我们只需要go thru string s, 注意这里我们可以对于每个word里面的字符c, 在mp[c]里面用binary search找大于它的最小位置,这样,我们go thru string s就可以跳着走了。这里我认为时间复杂度是O(nwlog(k)),这里n是words里面word的个数,w是每个word的平均长度,k是每个word里面的每个字符的平均重复数目。
如果我们用LintCode 1263的方法,那么时间复杂度是O(nwm)。这里m是s的长度。
class Solution {
public:
/**
* @param s: a string
* @param words: a dictionary of words
* @return: the number of words[i] that is a subsequence of S
*/
int numMatchingSubseq(string &s, vector<string> &words) {
int sizeS = s.size();
int n = words.size();
map<char, vector<int>> mp;
for (int i = 0; i < sizeS; i++) {
mp[s[i]].push_back(i);
}
int count = 0;
for (auto word : words) {
bool found = false;
int indexW = 0, indexS = 0;
while (indexS < sizeS) {
char c = word[indexW];
if (mp[c].empty()) break;
int pos = binarySearch(mp[c], indexS);
if (pos == -1) break;
else indexW++;
indexS = mp[c][pos] + 1;
}
if (indexW == word.size()) count++;
}
return count;
}
private:
int binarySearch(vector<int> &nums, int target) {
int start = 0, end = nums.size() - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] < target) {
start = mid;
} else {
end = mid;
}
}
if (nums[start] >= target) return start;
if (nums[end] >= target) return end;
return -1;
}
};