day12-459.重复的子字符串

459.重复的子字符串

力扣题目链接(opens new window)

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:

  • 输入: “abab”
  • 输出: True
  • 解释: 可由子字符串 “ab” 重复两次构成。

示例 2:

  • 输入: “aba”
  • 输出: False

示例 3:

  • 输入: “abcabcabcabc”
  • 输出: True
  • 解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)

思路

暴力解法

枚举所有子串,进行匹配。

以下是我的做法:

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
       string t = s+s;
       t.erase(t.begin());
       t.erase(t.end()-1);
        return t.find(s) != s.npos;
    }
};

若s为重复字串,那么s+s也必定为重复子字符串,而假设s的重复子字符串为a,则s+s的重复子字符串在中间必有一串a+a。根据这个特性,我们只需判断在s+s中是否有s即可,记得减去头尾。

KMP

KMP的本质是用来匹配模板字符串与原字符串的,在这里可以用作检测重复子字符串。

结论如下:若s为重复字符串,那么即最长公共前后缀不包含的即重复子字符串。

代码如下:

class Solution {
public:
    void getNext(vector<int> &next, string s)
    {
        int pre = 0;
        next[0] = pre;
        for (int suf = 1; suf < s.size(); ++suf) {
            while(pre > 0 && s[pre] != s[suf]){
                pre = next[pre -1];
            }
            if (s[pre] == s[suf])pre++;
            next[suf] = pre;
        }
    }
    bool repeatedSubstringPattern(string s) {
       vector<int>  next(s.size(),0);
       getNext(next,s);
       return next[s.size()-1] != 0&& s.size()%(s.size() - next[s.size()-1]) == 0 ;
    }
};

你可能感兴趣的:(算法,算法)