Leetcode:459. 重复的子字符串(C++)

目录

问题描述:

实现代码与解析:

 移动匹配法:

原理思路:

 利用kmp法:

原理思路:

暴力法:

原理思路:  


问题描述:

        给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

实现代码与解析:

 移动匹配法:

class Solution {
public:
    bool repeatedSubstringPattern(string s)
    {
        string t=s+s;//拼接
        t.erase(t.begin());//去头
        t.erase(t.end()-1);//去尾
        if(t.find(s)!=string::npos) return true;
        return false;
      
    }
};

        还有一种简短的写法:

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) != s.size();
    }
};

原理思路:

        满足条件的字符串一定可以找到前后子串相等的子串,我们将子串复制一份拼接在一起,这时,中间的字符串变为后子串加前子串,在其中找到原子串,说明这个字符串可由一个子串重复构成,至于为什么删除首字符和尾字符,因为我们要排除找到的是自身的字符串,确保找到的是我们拼接而来的。

        第二个简短代码,它是从下标为1开始找的,若不等于s.size(),也就是在找到末尾一定匹配的子串前,在中间没找到匹配的,所以说明该字符串不能由子串重复构成,与删除首尾字符原理相同。下面给出一个例子,便于理解。

Leetcode:459. 重复的子字符串(C++)_第1张图片

 利用kmp法:

class Solution {
public:
    //kmp获得next数组
    void getNext(int next[],string s)
    {
        int j=0;
        next[0]=0;
        for(int i=1;i0)
            {
                j=next[j-1];
            }
            if(s[j]==s[i])
            {
                j++;
            }
            next[i]=j;
        }
    }
    bool repeatedSubstringPattern(string s)
    {
        if(s.size()==0)
        {
            return false;
        }
        int next[s.size()];
        getNext(next,s);
        int len=s.size();
        if(next[len-1]!=0&&len%(len-next[len-1])==0)
        {
            return true;
        }
        return false;        
    }
};

原理思路:

        先说结论:前缀中,不包含最长公共前后缀相同的部分,即为组成该字符串的重复子串。原理需要推导,大家只要记住,前缀和后缀对应的位置字符相同,字符串数组中同一个下标的字符相同,这两点,就能理解为什么得出的这个结论。同样给出图片,便于大家理解:Leetcode:459. 重复的子字符串(C++)_第2张图片

        根据红线的连接就可以看出,最小重复子串是如何找出来的了,看不懂的话再看看我让大家注意的那两点。

暴力法:

class Solution {
public:
    bool repeatedSubstringPattern(string s)
    {
        int len=s.size();
        for(int i=1;i<=len/2;i++)
        {
            string temp;
            if(len%i!=0)
            {
                continue;
            }
            //完整拼接复原
            for(int j=0;j

原理思路:  

        直接暴力法把所有的可能找出来,比较简单和好理解,就是循环遍历,根据倍数拼接,然后复原,看是否与原字符串相等。

你可能感兴趣的:(LeetCode,leetcode,c++,java)