mgaw

导航

代码随想录算法训练营第九天| 28 找出字符串中第一个匹配项的下标 459 重复的子字符串

目录

28 找出字符串中第一个匹配项的下标

暴力解法

KMP解法

459 重复的子字符串

暴力解法

KMP解法


28 找出字符串中第一个匹配项的下标

暴力解法

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(),m = needle.length();
        char s[] = haystack.toCharArray();
        char p[] = needle.toCharArray();
        for(int i = 0;i < n - m + 1;i++){//n与m会出现相等的情况
            int a = i,b = 0;
            while(b < m && s[a] == p[b]){
                a++;b++;
            }
            if(b == m)return i;//完全匹配,返回下标
        }
        return -1;
    }
}

时间复杂度O((n - m) * m)

空间复杂度O(1)

KMP解法

文本串:aabaabaafa

模式串str:aabaaf

要判断模式串s是否在文本串中

前缀:对于字符串str,a,aa,aab,aaba,aabaa均为s的前缀(不包括它本身)

后缀:对于字符串str,f,af,aaf,baaf,abaaf均为s的后缀(不包括它本身)

class Solution {
    public int strStr(String haystack, String needle) {
        //haystack文本串,needle模式串,需要判断needle是否在haystack中
        int n = haystack.length();
        int m = needle.length();
        haystack = " " + haystack;
        needle = " " + needle;//添加空格,使下标从1开始
        char s[] = haystack.toCharArray();
        char p[] = needle.toCharArray();
        int next[] = new int[m + 1];//p数组下标从1开始,所以next数组开m + 1的大小
        for(int i = 2,j = 0;i <= m;i++){//i从2开始,i为1时相同前后缀为0
            while(j > 0 && p[i] != p[j + 1])j = next[j];//公共前后缀匹配不成功,j取上一次的值
            if(p[i] == p[j + 1])j++;//相同前后缀匹配成功
            next[i] = j;//更新next[i]的值
        }
        for(int i = 1,j = 0;i <= n;i++){
            while(j > 0 && s[i] != p[j + 1])j = next[j];
            if(s[i] == p[j + 1])j++;
            if(j == m)return i - m;//整个段匹配成功,返回下标
        }
        return -1;
    }
}

时间复杂度O(n + m)

空间复杂度O(m)

459 重复的子字符串

暴力解法

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int n = s.length();
        for(int i = 1;i * 2 <= n;i++){//子串一定小于等于s的一半
            if(n % i == 0){
                boolean match = true;
                for(int j = i;j < n;j++){
                    if(s.charAt(j) != s.charAt(j - i)){
                        match = false;
                        break;
                    }
                }
                if(match)return true;
            }
        }
        return false;
    }
}

时间复杂度O(n^2)

空间复杂度O(1)

KMP解法

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int len = s.length();
        s = " " + s;
        char chars[] = s.toCharArray();
        int next[] = new int[len + 1];
        for(int i = 2,j = 0;i <= len;i++){
            //匹配不成功,赋予j前一个位置next数组对应的值
            while(j > 0 && chars[i] != chars[j + 1])j = next[j];
            //匹配成功,j往后移
            if(chars[i] == chars[j + 1])j++;
            next[i] = j;
        }
        if(next[len] > 0 && len % (len - next[len]) == 0)return true;
        return false;
    }
}

时间复杂度O(n)

空间复杂度O(n)

posted on 2023-11-01 19:05  A魔法恐龙  阅读(12)  评论(0)    收藏  举报  来源