算法-KMP-重复的子字符串

算法-KMP-重复的子字符串

1 题目概述

1.1 题目出处

https://leetcode-cn.com/problems/repeated-substring-pattern/solution/java-yi-xing-dai-ma-jie-jue-zhong-fu-zi-chuan-wen-/

1.2 题目描述

在这里插入图片描述

2 暴力枚举法

2.1 思路

从长度为1的窗口开始翻滚,每次用substring方法比较,如果不同,就停止,并将窗口大小加一再次比较。

2.2 代码

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        if(s == null){
            return false;
        }

        for(int i = 1; i <= s.length() / 2; i++){
            String base = s.substring(0, i);
            int j = i;
            // j <= s.length() - i是防止数组越界
            for(; j <= s.length() - i; j += i){
                if(!s.substring(j, j + i).equals(base)){
                    break;
                }
            }
            if(j >= s.length()){
                return true;
            }
        }
        return false;
    }
}

2.3 时间复杂度

在这里插入图片描述

3 枚举法-优化

3.1 思路

从长度为1的窗口开始翻滚,每次用substring方法比较,如果不同,就停止,并将窗口大小加一再次比较。

但有个优化,即每次取窗口长度时,先判断是否能被字符串长度整除,如果不行直接跳过该大小的窗口。

3.2 代码

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        if(s == null){
            return false;
        }

        for(int i = 1; i <= s.length() / 2; i++){
            if(s.length() % i != 0){
                continue;
            }
            String base = s.substring(0, i);
            int j = i;
            for(; j < s.length() ; j += i){
                if(!s.substring(j, j + i).equals(base)){
                    break;
                }
            }
            if(j >= s.length()){
                return true;
            }
        }
        return false;
    }
}

3.3 时间复杂度

在这里插入图片描述
O(N^2)

  • N为字符串总长,枚举窗口长度时间复杂度O(N);每次窗口翻滚时间复杂度O(N),所以是O(N^2)

3.4 空间复杂度

O(1)

4 字符串匹配

4.1 思路

重复的子字符串-官方题解方法3可证明,要求重复的子字符串,只要将该字符串重复一次append在该字符串后面,并去掉首位字符串,得到的字符串只要contains原始字符串,那就说明可由重复的子字符串构成。

也可以参考简单明了!!关于java两行代码实现的思路来源

4.2 代码

if(s == null){
            return false;
        }
        return (s + s).substring(1, s.length()*2-1).contains(s);

4.3 时间复杂度

在这里插入图片描述

4.4 空间复杂度

O(1)

参考文档

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值