LeetCode——判断子序列

Q:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

示例 1:
s = "abc", t = "ahbgdc"
返回 true.

示例 2:
s = "axc", t = "ahbgdc"
返回 false.

A:
双指针

    public boolean isSubsequence(String s, String t) {
        if (s.length() == 0)
            return true;
        if (t.length() == 0 || t.length() < s.length())
            return false;
        int indexs = 0;
        int indext = 0;
        while (indexs < s.length() && indext < t.length()) {
            if (s.charAt(indexs) == t.charAt(indext)) {
                indexs++;
            }
            indext++;
        }
        return indexs == s.length();
    }

还有一个利用java本身的函数的,特别方便:java中String类有这样一个方法public int indexOf(int ch, int fromIndex) ,他表示的是在字符串中是否存在一个字符ch,并且是从字符串的下标fromIndex开始查找的。我们要做的是在t字符串中查找s中的每一个字符,如果没查到,直接返回false。如果查到,就从t的下一个位置继续开始查

    public boolean isSubsequence(String s, String t) {
        int index = -1;
        for (char c : s.toCharArray()) {
            //index表示上一次查找的位置(第一次查找的时候为-1),所以这里要从t的下标(index+1)开始查找
            index = t.indexOf(c, index + 1);
            //没找到,返回false
            if (index == -1)
                return false;
        }
        return true;
    }

后续挑战 :
如果有大量输入的 S,称作S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
引用:对后续挑战的一些思考--如何快速判断大量字符串
我们前期多做一点工作,将长字符串研究透彻,假如长字符串的长度为 nn,建立一个 n * 26n∗26 大小的矩阵,表示每个位置上26个字符下一次出现的位置,对于要匹配的短字符串,遍历每一个字符,不断地寻找该字符在长字符串中的位置,然后将位置更新,寻找下一个字符,相当于在长字符串上“跳跃”。如果下一个位置为 -1,表示长字符串再没有该字符了,返回 false 即可。

    public boolean isSubsequence(String s, String t) {

        //考虑到  对第一个字符的处理 ,在t 之前一个空字符
        t=' '+t;

        //对t长字符串 做预处理
        int[][] dp = new int[t.length()][26];//存储每一个位置上  a--z的下一个字符出现的位置
        for (char c = 'a'; c <= 'z'; c++) {//依次对每个字符作处理
            int nextPos = -1;//表示接下来不会在出现该字符

            for (int i = t.length() - 1; i >= 0; i--) {//从最后一位开始处理
                dp[i][c - 'a'] = nextPos;//dp[i][c-'a']  加上外层循环  就是对每一个位置的a---z字符的处理了
                if (t.charAt(i) == c) {//表示当前位置有该字符  那么指向下一个该字符出现的位置就要被更新为i
                    nextPos = i;
                }
            }
        }

        //数据的利用 ,开始匹配
        int index=0;
        for (char c:s.toCharArray()){
            index=dp[index][c-'a'];//因为加了' ',所以之后在处理第一个字符的时候  如果是在第一行,就会去第一行,不影响之后字符的判断
            if(index==-1){
                return false;
            }
        }
        return true;
    }
原文地址:https://www.cnblogs.com/xym4869/p/13463580.html