Description
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
1.All words in words and S will only consists of lowercase letters.
2.The length of S will be in the range of [1, 50000].
3.The length of words will be in the range of [1, 5000].
4.The length of words[i] will be in the range of [1, 50].
Solution 1(C++)
class Solution {
public:
int numMatchingSubseq (string S, vector<string>& words) {
vector<vector<int>> alpha (26);
for (int i = 0; i < S.size (); ++i) alpha[S[i] - 'a'].push_back (i);
int res = 0;
for (const auto& word : words) {
int x = -1;
bool found = true;
for (char c : word) {
auto it = upper_bound (alpha[c - 'a'].begin (), alpha[c - 'a'].end (), x);
if (it == alpha[c - 'a'].end ()) found = false;
else x = *it;
}
if (found) res++;
}
return res;
}
};
算法分析
要注意,单纯的暴力算法会超时,所以需要先遍历一般S,记录26个字母出现的各自位置,然后去搜索words中,每一个word中各个字符出现的位置。
程序分析
upper_bound与lower_bound都是在左闭右开的区间中进行的二分查找算法:
- upper_bound:返回的是被查序列中第一个大于查找值的指针,也就是返回指向被查值>查找值的最小指针。或者说:对于给定的已经排好序的a,key最晚能插入到那个位置
- lower_bound:返回的是被查序列中第一个大于等于查找值的指针,也就是返回指向被查值>=查找值的最小指针。或者说:对于给定的已经排好序的a,key最早能插入到那个位置