题目:就是给两个字符串s和t,来判断s是否是t的的子字符串,注意的是,作为子字符串或者说是子序列,可以不用必须是连贯的,可以中间隔几个,例如,"ace""abcde"的一个子序列,而"aec"不是。

解题:

首先我啥也不管,来个笨法

还是双循环,但是有两个标记位,一个标记位count是来得到s字符串符合条件的和,(举个例子,s是asdfger,t是 sag,可以看出来这不是子字符串,只有s和g符合条件在t中找到对应的位置,所以count是2,不等于s的长度,所以不是子串)

一个标记位是记录匹配到对应的位置,下一次循环要从记录位置下一步去找,保证顺序。

来,代码展示



public boolean isSubsequence(String s, String t) {
      char[] sArray = s.toCharArray();
        char[] tArray = t.toCharArray();

        int point = 0;
        int count = 0;

        for( char son : sArray ){
            for(int i = point  ; i< tArray.length ; i++ ){
                if(son == tArray[i] ){
                    point = i + 1;
                    count += 1;
                    break;
                }
            }
        }

        if(count >= sArray.length){
            return true;
        }else {
            return false;
        }
    }



第二,理解是好理解,但是代码长度有点长,如果不注意代码会出错(比如说忘记break,比如说 point位置没有加一,遇到重复的字符串就会出现问题)

所以还有一个双指针法,所谓的双指针法,算是贪心算法的一种,就是把所有的都找出来看看有没有符合条件的

所以双指针的退出条件就是,两个字符串长度是否遍历完。



public boolean isSubsequence(String s, String t) {
       int n = s.length(), m = t.length();
        int i = 0, j = 0;
        while (i < n && j < m) {
            if (s.charAt(i) == t.charAt(j)) {
                i++;
            }
            j++;
        }
        return i == n;
    }



遍历是遍历,咋样判断是否完全匹配呢,实际上还是要靠匹配的长度(跟我那个专门拿出一个记录总数不一样,他是直接循环,看短的字符串那一步执行不下去,然后再看这个长度是不是短字符串长度来判断)

时间复杂度我觉得应该是O(m+n),为什么不是O(m)那?最差情况每一步都要走,举个例子两个字符串是一样的,while是ture一直往下走,导致循环的每一步都符合不中断,一直走,最后是m+n

第三 动态规划DP

万物皆DP,也是没谁了,主要的操作就是先对数据预处理(对t或者说是父字符串),然后s过来匹配。

首先介绍一个比较不错的博客关于这个题目的动态规划题解



hive SQL判断字符串开头 hive判断字符串是否为字母_hive SQL判断字符串开头


所谓的预处理就是把父字符串做个处理,画个表,第一步是这种


hive SQL判断字符串开头 hive判断字符串是否为字母_动态顺序字符串基本操作实验_02


我们要开始填数字,填数字,注意填6的地方表示没用,或者是用不到,不好理解的话可以画X,我懒拿别人的图片就不多比比了。

填数字要注意是倒着填,ahbgdc,从c开始,而且每填完一个就上一个可以填的少一个

填完后类似这种


hive SQL判断字符串开头 hive判断字符串是否为字母_字符串_03


当然你会发现,t字符串还会出现重复的字符,这样的咋填,没事还是同样方法,只不过会覆盖上去,例如ahbgdb


hive SQL判断字符串开头 hive判断字符串是否为字母_可以同 == 判断两个string_04


然后结合官方解答方程和题解就能有一个大概的想法啦(最起码不会一脸问号,实际我也走到这一步稍微有点思路,也不能说完整的理解得很好,但是中间有很大一步都在预处理上了。)

官方动态规划


public boolean isSubsequence(String s, String t) {
        int n = s.length(), m = t.length();

        int[][] f = new int[m + 1][26];
        for (int i = 0; i < 26; i++) {
            f[m][i] = m;
        }

        for (int i = m - 1; i >= 0; i--) {
            for (int j = 0; j < 26; j++) {
                if (t.charAt(i) == j + 'a')
                    f[i][j] = i;
                else
                    f[i][j] = f[i + 1][j];
            }
        }
        int add = 0;
        for (int i = 0; i < n; i++) {
            if (f[add][s.charAt(i) - 'a'] == m) {
                return false;
            }
            add = f[add][s.charAt(i) - 'a'] + 1;
        }
        return true;
    }