zoukankan      html  css  js  c++  java
  • 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;
        }
    
  • 相关阅读:
    Avito Cool Challenge 2018:D. Maximum Distance
    Avito Cool Challenge 2018:C. Colorful Bricks
    Struts2开发基本步骤
    hibernate query.list() 返回的数据类型
    hibernate query.list() 返回的数据类型
    HibernateUtil工具类
    Hibernate实现步骤
    Hibernate实现步骤
    分页关键知识点总结
    详解
  • 原文地址:https://www.cnblogs.com/xym4869/p/13463580.html
Copyright © 2011-2022 走看看