给定两个数组s和t(只包含小写字母),判断s是否为t删除若干字符后得到的子串。
若单纯判断是否为子串,过程比较简单,只需要设置两个指针。
public boolean isSubsequence(String s, String t) {
int is = 0, it = 0;
while(is < s.length() && it < t.length()){
if(s.charAt(is) == t.charAt(it)) is++;
it++;
}
if(is == s.length()) return true;
else return false;
}
若s比较短(小于100个字符),而t比较长(长至50000个字符),且s的个数比较多,需要不断的寻找和判断s中是否有t的子串,此时就要对算法进行改进。
因为s和t只包含小写字母,因此即使t长度比较长,但还是由26个字母组成的,可以把t中每个字母出现的下标记录下来,然后根据下标来判断:对于s中的后续字母,其在t中有比其前面字母大的下标。
public boolean isSubsequence(String s, String t) {
List<List<Integer>> indexList = new ArrayList<List<Integer>>();
for(int i = 0; i <= 26; i++){
indexList.add(new ArrayList<Integer>());
}
for(int i = 0; i < t.length(); i++){
indexList.get(t.charAt(i) - 'a').add(i); //把下标存入队列
}
int index = -1;
for(int i = 0; i < s.length(); i++){
int order = s.charAt(i) - 'a'; //字母在列表中的位置
if(indexList.get(order).size() == 0) return false; //t中没有该字符
int j = 0;
while(indexList.get(order).size() > j && indexList.get(order).get(j) <= index) j++; //找到比前序大的下标
if(indexList.get(order).size() == j) return false; //没有比前序大的下标,说明不是t中不存在出现在其前序之后的该字符
else index = indexList.get(order).get(j); //修改当前下标
}
return true; //s遍历完毕,没有返回false,说明所有字符都找到对应的下标了
}