给定一个字符串S 和一个单词字典 words,问, words中一共有多少个单词words[i]是字符串S的子序列?
注意, 子序列不同于子串, 子序列不要求连续.
这题的一种容易懂的解法是这样的
把字符串S里的所有字符统计一下,记录它们出现的位置
然后判断一个个word是不是它的子序列的时候,
一个个字符去扫描
假设这个单词是abc, 原串是adsferertbca
一开始找到了a的最左边的Index 0,
那我在找第二个字母b的时候,b必须要出现在之前index的后面
第三个字母c,也必须出现在前面的index的后面
所以扫描的时候记录一下之前找到的index就可以了
为了快速查找,用treeset实现o(logn)找index
public int numMatchingSubseq(String s, String[] words) {
Map<Character, TreeSet<Integer>> map = new HashMap();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
TreeSet<Integer> set = map.getOrDefault(c, new TreeSet());
set.add(i);
map.put(c, set);
}
int res = 0;
for(String t: words) {
if(isSebseq(t, map)) res++;
}
return res;
}
private boolean isSebseq(String s, Map<Character, TreeSet<Integer>> map) {
int prev = -1;
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
TreeSet<Integer> set = map.get(c);
if(set == null) return false;
Integer high = set.higher(prev);
if(high == null) return false;
prev = high;
}
return true;
}