# 青云算法面试题干货-字符串的子串-LeetCode第792题

public int numMatchingSubseq(String S, String[] words) {
int count = 0;
for (String word : words) {
if (matchingSubseq(S, word)) {
count++;
}
}

return count;
}

private boolean matchingSubseq(String S, String word) {
int i = 0, j = 0;
while (i < S.length() && j < word.length()) {
if (S.charAt(i) == word.charAt(j)) {
i++;
j++;
} else {
i++;
}
}

return j == word.length();
}


public int numMatchingSubseq(String S, String[] words) {
ArrayList<Integer>[] letterIndices = new ArrayList[26];
for (int i = 0; i < 26; ++i) {
letterIndices[i] = new ArrayList<>();
}

for (int i = 0; i < S.length(); ++i) {
}

int count = 0;
for (String word : words) {
if (matchingSubseq(S, word, letterIndices)) {
count++;
}
}

return count;
}

private boolean matchingSubseq(String S, String word,
ArrayList<Integer>[] letterIndices) {
int i = 0, j = 0;
while (i < S.length() && j < word.length()) {
int next = findIndex(letterIndices[word.charAt(j) - 'a'], i);
if (next < 0) {
return false;
}

i = next + 1;
j++;
}

return j == word.length();
}

private int findIndex(ArrayList<Integer> indices, int i) {
int start = 0, end = indices.size() - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (indices.get(mid) >= i) {
if (mid == 0 || indices.get(mid - 1) < i) {
return indices.get(mid);
}

end = mid - 1;
} else {
start = mid + 1;
}
}

return -1;
}


public int numMatchingSubseq(String S, String[] words) {
TreeSet<Integer>[] letterIndices = new TreeSet[26];
for (int i = 0; i < 26; ++i) {
letterIndices[i] = new TreeSet<>();
}

for (int i = 0; i < S.length(); ++i) {
}

int count = 0;
for (String word : words) {
if (matchingSubseq(S, word, letterIndices)) {
count++;
}
}

return count;
}

private boolean matchingSubseq(String S, String word,
TreeSet<Integer>[] letterIndices) {
int i = 0, j = 0;
while (i < S.length() && j < word.length()) {
Integer next = letterIndices[word.charAt(j) - 'a'].ceiling(i);
if (next == null) {
return false;
}

i = next + 1;
j++;
}

return j == word.length();
}