[LeetCode] Repeated Substring Pattern

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

Example 1:

Input: "abab"

Output: True

Explanation: It's the substring "ab" twice.

Example 2:

Input: "aba"

Output: False

Example 3:

Input: "abcabcabcabc"

Output: True

Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)

重复子字符串模板:给定源一个字符串,如果它是由重复的子串组成,则返回true,否则返回false。

1、如果一个字符串由重复的子串组成,那么先枚举所有的子字符串。子字符串的最大长度小于等于源字符串长度的一半。

2、枚举出每一个子字符串后,根据它的长度来判断它是否组成源字符串。

3、判断标准:1)首先子字符串长度要被源字符串整除。2)以子字符串的长度为界,依次取源字符串的子串。判断每个子串是否和枚举的子字符串相等。如果不等,则跳出判断循环,枚举下一个子字符串。

复制代码
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        for (int i = 1; i <= n / 2; i++) {
            if (n % i == 0) {
                string sub = s.substr(0, i);
                int j;
                for (j = 1; j < n / i; j++) 
                    if (sub != s.substr(i * j, i))
                        break;
                if (j == n / i)
                    return true;
            }
        }
        return false;
    }
};
// 33 ms
复制代码

 简便方法:

1、令str = s + s

2、然后将str取掉首尾字符

3、在新的str中寻找s,如果找到返回true,否则返回false

复制代码
public:
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        string str = s + s;
        str = str.substr(1, 2 * n - 2);
        return str.find(s) != -1;
    }
};
// 29 ms
复制代码

 kmp方法。

假设str长度为len,重复的子串长度为k,则如果真的由连续多个长度为k的子串重复构成str,那么在对str求next时,由于连续对称性(如图,前后两个虚线框内字符串相等),会从next[k+1]开始,1,2,3...地递增,直到next[len]=len-k,且(len-k)%k==0,表示有整数个k

要一直求到next[len]而不是next[len-1],是因为next[len-1]只是表示前len-1个字母的内部对称性,而没有考虑到最后一个字母即str[len-1]

所以求解很简单:先对str求next数组,一直求到next[len],然后看看next[len]是否非零且整除k(k=len-next[len])

复制代码
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        vector<int> dp(n + 1, 0);
        dp[0] = -1;
        int j = 0, k = -1;
        while (j < n) {
            if (k == -1 || s[j] == s[k])
                dp[++j] = ++k;
            else
                k = dp[k];
        }
        return dp[n] && (dp[n] % (n - dp[n]) == 0);
    }
};
// 42 ms
复制代码

 参考:http://www.cnblogs.com/liziran/p/6129336.html

 

posted @   immjc  阅读(134)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
点击右上角即可分享
微信分享提示