题目简介: 给定字符串 s
和字符串数组 words
, 返回 words[i]
中是s
的子序列的单词个数 。
字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。
例如, “ace”
是 “abcde”
的子序列。
示例 1:
1 2 3 输入: s = "abcde", words = ["a","bb","acd","ace"] 输出: 3 解释: 有三个是 s 的子序列的单词: "a", "acd", "ace"。
提示:
1 <= s.length <= 5 * 10^4
1 <= words.length <= 5000
1 <= words[i].length <= 50
words[i]
和 s 都只由小写字母组成。
思路: 首先我们将s
中所有字符的下标放至对应的位置,方便后续查找,即map[c]
中放置的都是字符c
的下标。
遍历每个word
,用二分来查找每个字符的下标,若找不到,则说明不符合题意,舍去。
tip:
代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution {public : int numMatchingSubseq (string s, vector <string >& words) { vector <vector <int >> map (26 , vector <int >()); for (int i = 0 ; i < s.size(); i++){ map [s[i] - 'a' ].push_back(i); } int res = 0 ; for (auto & word : words){ if (word.size() > s.size()) continue ; int begin = -1 ; int flag = 0 ; for (int i = 0 ; i < word.size(); i++){ auto & now_map = map [word[i] - 'a' ]; auto j = upper_bound(now_map.begin(), now_map.end(), begin); if (j == now_map.end()){ flag = 1 ; break ; } begin = *j; } if (flag == 0 ) res++; } return res; } };