给定字符串 S 和单词字典 words, 求 words[i] 中是 S 的子序列的单词个数。
示例:
输入:
S = "abcde"
words = ["a", "bb", "acd", "ace"]
输出: 3
解释: 有三个是 S 的子序列的单词: "a", "acd", "ace"。
注意:
所有在words和 S 里的单词都只由小写字母组成。
S 的长度在 [1, 50000]。
words 的长度在 [1, 5000]。
words[i]的长度在[1, 50]。
思路:可以开一个map用来存储原串中每种字符所有出现的位置索引,再开一个数组用来存储当前匹配过程中每种字符已经用到了第几个,同时判断是否能够往下继续进行匹配。
class Solution {
public int numMatchingSubseq(String S, String[] words) {
int ans=0;
int[] p=new int[26];
Map<Character,List<Integer>> map=new HashMap<>();
for(int i=0;i<S.length();i++) {
if(!map.containsKey(S.charAt(i)))
map.put(S.charAt(i), new ArrayList<>());
map.get(S.charAt(i)).add(i);
}
for(int i=0;i<words.length;i++) {
for(int j=0;j<26;j++) p[j]=0;
int index=0,len=words[i].length(),loc=-1;
while(index>=0 && index<len) {
if(!map.containsKey(words[i].charAt(index))) break;
int id=words[i].charAt(index)-'a';
char c=words[i].charAt(index);
while(p[id]<map.get(c).size() && map.get(c).get(p[id])<=loc)
p[id]++;
if(p[id]==map.get(c).size()) break;
loc=map.get(c).get(p[id]);
index++;
}
if(index==len) ans++;
}
return ans;
}
}